下面列出了 io.netty.handler.codec.http2.HttpConversionUtil.ExtensionHeaderNames #software.amazon.awssdk.utils.StringUtils 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public AwsCredentials resolveCredentials() {
String accessKey = environment.getProperty(ACCESS_KEY_ENV_VAR, String.class, environment.getProperty(ALTERNATE_ACCESS_KEY_ENV_VAR, String.class, (String) null));
String secretKey = environment.getProperty(SECRET_KEY_ENV_VAR, String.class, environment.getProperty(ALTERNATE_SECRET_KEY_ENV_VAR, String.class, (String) null));
accessKey = StringUtils.trim(accessKey);
secretKey = StringUtils.trim(secretKey);
String sessionToken = StringUtils.trim(environment.getProperty(AWS_SESSION_TOKEN_ENV_VAR, String.class, (String) null));
if (StringUtils.isBlank(accessKey) || StringUtils.isBlank(secretKey)) {
throw SdkClientException.create(
"Unable to load AWS credentials from environment "
+ "(" + ACCESS_KEY_ENV_VAR + " (or " + ALTERNATE_ACCESS_KEY_ENV_VAR + ") and "
+ SECRET_KEY_ENV_VAR + " (or " + ALTERNATE_SECRET_KEY_ENV_VAR + "))");
}
return sessionToken == null
? AwsBasicCredentials.create(accessKey, secretKey)
: AwsSessionCredentials.create(accessKey, secretKey, sessionToken);
}
private String standardizePath(String path) {
if (StringUtils.isEmpty(path)) {
return "";
}
StringBuilder standardizedPath = new StringBuilder();
// Path must always start with '/'
if (!path.startsWith("/")) {
standardizedPath.append('/');
}
standardizedPath.append(path);
return standardizedPath.toString();
}
/**
* Encode a string for use in the path of a URL; uses URLEncoder.encode,
* (which encodes a string for use in the query portion of a URL), then
* applies some postfilters to fix things up per the RFC. Can optionally
* handle strings which are meant to encode a path (ie include '/'es
* which should NOT be escaped).
*
* @param value the value to encode
* @param ignoreSlashes true if the value is intended to represent a path
* @return the encoded value
*/
private static String urlEncode(String value, boolean ignoreSlashes) {
if (value == null) {
return null;
}
String encoded = invokeSafely(() -> URLEncoder.encode(value, DEFAULT_ENCODING));
if (!ignoreSlashes) {
return StringUtils.replaceEach(encoded,
ENCODED_CHARACTERS_WITHOUT_SLASHES,
ENCODED_CHARACTERS_WITHOUT_SLASHES_REPLACEMENTS);
}
return StringUtils.replaceEach(encoded, ENCODED_CHARACTERS_WITH_SLASHES, ENCODED_CHARACTERS_WITH_SLASHES_REPLACEMENTS);
}
/**
* Configures the headers in the specified Netty HTTP request.
*/
private void addHeadersToRequest(DefaultHttpRequest httpRequest, SdkHttpRequest request) {
httpRequest.headers().add(HOST, getHostHeaderValue(request));
String scheme = request.getUri().getScheme();
if (Protocol.HTTP2 == protocol && !StringUtils.isBlank(scheme)) {
httpRequest.headers().add(ExtensionHeaderNames.SCHEME.text(), scheme);
}
// Copy over any other headers already in our request
request.headers().entrySet().stream()
/*
* Skip the Host header to avoid sending it twice, which will
* interfere with some signing schemes.
*/
.filter(e -> !IGNORE_HEADERS.contains(e.getKey()))
.forEach(e -> e.getValue().forEach(h -> httpRequest.headers().add(e.getKey(), h)));
}
@Override
public List<MethodSpec> beanStyle() {
List<MethodSpec> methods = new ArrayList<>();
methods.add(beanStyleSetterBuilder()
.addCode(beanCopySetterBody())
.build());
if (StringUtils.isNotBlank(memberModel().getDeprecatedBeanStyleSetterMethodName())) {
methods.add(deprecatedBeanStyleSetterBuilder()
.addCode(beanCopySetterBody())
.addAnnotation(Deprecated.class)
.addJavadoc("@deprecated Use {@link #" + memberModel().getBeanStyleSetterMethodName() + "} instead")
.build());
}
return methods;
}
private MethodSpec mergeServiceDefaultsMethod() {
boolean crc32FromCompressedDataEnabled = model.getCustomizationConfig().isCalculateCrc32FromCompressedData();
MethodSpec.Builder builder = MethodSpec.methodBuilder("mergeServiceDefaults")
.addAnnotation(Override.class)
.addModifiers(PROTECTED, FINAL)
.returns(SdkClientConfiguration.class)
.addParameter(SdkClientConfiguration.class, "config")
.addCode("return config.merge(c -> c.option($T.SIGNER, defaultSigner())\n",
SdkAdvancedClientOption.class)
.addCode(" .option($T"
+ ".CRC32_FROM_COMPRESSED_DATA_ENABLED, $L)",
SdkClientOption.class, crc32FromCompressedDataEnabled);
String clientConfigClassName = model.getCustomizationConfig().getServiceSpecificClientConfigClass();
if (StringUtils.isNotBlank(clientConfigClassName)) {
builder.addCode(".option($T.SERVICE_CONFIGURATION, $T.builder().build())",
SdkClientOption.class, ClassName.bestGuess(clientConfigClassName));
}
builder.addCode(");");
return builder.build();
}
@Override
public String getEnumValueName(String enumValue) {
String result = enumValue;
// Special cases
result = result.replaceAll("textORcsv", "TEXT_OR_CSV");
// Split into words
result = String.join("_", splitOnWordBoundaries(result));
// Enums should be upper-case
result = StringUtils.upperCase(result);
if (!result.matches("^[A-Z][A-Z0-9_]*$")) {
String attempt = result;
log.warn(() -> "Invalid enum member generated for input '" + enumValue + "'. Best attempt: '" + attempt + "' If this "
+ "enum is not customized out, the build will fail.");
}
return result;
}
/**
* Tries to find the member model associated with the given c2j member name from this shape
* model. Returns the member model if present else returns null.
*/
private MemberModel tryFindMemberModelByC2jName(String memberC2jName, boolean ignoreCase) {
List<MemberModel> memberModels = getMembers();
String expectedName = ignoreCase ? StringUtils.lowerCase(memberC2jName)
: memberC2jName;
if (memberModels != null) {
for (MemberModel member : memberModels) {
String actualName = ignoreCase ? StringUtils.lowerCase(member.getC2jName())
: member.getC2jName();
if (expectedName.equals(actualName)) {
return member;
}
}
}
return null;
}
private String deriveMarshallerLocationName(Shape memberShape, String memberName, Member member, String protocol) {
String queryName = member.getQueryName();
if (StringUtils.isNotBlank(queryName)) {
return queryName;
}
String locationName;
if (Protocol.EC2.getValue().equalsIgnoreCase(protocol)) {
locationName = deriveLocationNameForEc2(member);
} else if (memberShape.getListMember() != null && memberShape.isFlattened()) {
locationName = deriveLocationNameForListMember(memberShape, member);
} else {
locationName = member.getLocationName();
}
if (StringUtils.isNotBlank(locationName)) {
return locationName;
}
return memberName;
}
/**
* Read a profile line and update the parser state with the results. This marks future properties as being in this profile.
*
* Configuration Files: [ Whitespace? profile Whitespace Identifier Whitespace? ] Whitespace? CommentLine?
* Credentials Files: [ Whitespace? Identifier Whitespace? ] Whitespace? CommentLine?
*/
private static void readProfileDefinitionLine(ParserState state, String line) {
// Profile definitions do not require a space between the closing bracket and the comment delimiter
String lineWithoutComments = removeTrailingComments(line, "#", ";");
String lineWithoutWhitespace = StringUtils.trim(lineWithoutComments);
Validate.isTrue(lineWithoutWhitespace.endsWith("]"),
"Profile definition must end with ']' on line " + state.currentLineNumber);
Optional<String> profileName = parseProfileDefinition(state, lineWithoutWhitespace);
// If we couldn't get the profile name, ignore this entire profile.
if (!profileName.isPresent()) {
state.ignoringCurrentProfile = true;
return;
}
state.currentProfileBeingRead = profileName.get();
state.currentPropertyBeingRead = null;
state.ignoringCurrentProfile = false;
state.ignoringCurrentProperty = false;
// If we've seen this profile before, don't override the existing properties. We'll be merging them.
state.profiles.computeIfAbsent(profileName.get(), i -> new LinkedHashMap<>());
}
/**
* Read a property continuation line and update the parser state with the results. This adds the value in the continuation
* to the current property, prefixed with a newline.
*
* Non-Blank Parent Property: Whitespace Value Whitespace?
* Blank Parent Property (Sub-Property): Whitespace Identifier Whitespace? = Whitespace? Value Whitespace?
*/
private static void readPropertyContinuationLine(ParserState state, String line) {
// If we're in an invalid profile or property, ignore its continuations
if (state.ignoringCurrentProfile || state.ignoringCurrentProperty) {
return;
}
Validate.isTrue(state.currentProfileBeingRead != null && state.currentPropertyBeingRead != null,
"Expected a profile or property definition on line " + state.currentLineNumber);
// Comments are not removed on property continuation lines. They're considered part of the value.
line = StringUtils.trim(line);
Map<String, String> profileProperties = state.profiles.get(state.currentProfileBeingRead);
String currentPropertyValue = profileProperties.get(state.currentPropertyBeingRead);
String newPropertyValue = currentPropertyValue + "\n" + line;
// If this is a sub-property, make sure it can be parsed correctly by the CLI.
if (state.validatingContinuationsAsSubProperties) {
parsePropertyDefinition(state, line);
}
profileProperties.put(state.currentPropertyBeingRead, newPropertyValue);
}
/**
* Given a property line, load the property key and value. If the property line is invalid and should be ignored, this will
* return empty.
*/
private static Optional<Pair<String, String>> parsePropertyDefinition(ParserState state, String line) {
int firstEqualsLocation = line.indexOf('=');
Validate.isTrue(firstEqualsLocation != -1, "Expected an '=' sign defining a property on line " + state.currentLineNumber);
String propertyKey = StringUtils.trim(line.substring(0, firstEqualsLocation));
String propertyValue = StringUtils.trim(line.substring(firstEqualsLocation + 1));
Validate.isTrue(!propertyKey.isEmpty(), "Property did not have a name on line " + state.currentLineNumber);
// If the profile name includes invalid characters, it should be ignored.
if (!isValidIdentifier(propertyKey)) {
log.warn(() -> "Ignoring property '" + propertyKey + "' on line " + state.currentLineNumber + " because " +
"its name was not alphanumeric with only these special characters: - / . % @ _ :");
return Optional.empty();
}
return Optional.of(Pair.of(propertyKey, propertyValue));
}
/**
* Reads and stores the mime type setting corresponding to a file extension, by reading
* text from an InputStream. If a mime type setting already exists when this method is run,
* the mime type value is replaced with the newer one.
*/
private void loadAndReplaceMimetypes(InputStream is) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
br.lines().filter(line -> !line.startsWith("#")).forEach(line -> {
line = line.trim();
StringTokenizer st = new StringTokenizer(line, " \t");
if (st.countTokens() > 1) {
String mimetype = st.nextToken();
while (st.hasMoreTokens()) {
String extension = st.nextToken();
extensionToMimetype.put(StringUtils.lowerCase(extension), mimetype);
}
}
});
}
@Override
public SdkHttpFullRequest marshall(T in) {
SdkHttpFullRequest.Builder marshalled = delegateMarshaller.marshall(in).toBuilder();
marshalled.contentStreamProvider(requestBody.contentStreamProvider());
String contentType = marshalled.firstMatchingHeader(CONTENT_TYPE)
.orElse(null);
if (StringUtils.isEmpty(contentType)) {
marshalled.putHeader(CONTENT_TYPE, requestBody.contentType());
}
// Currently, SDK always require content length in RequestBody. So we always
// send Content-Length header for sync APIs
// This change will be useful if SDK relaxes the content-length requirement in RequestBody
addHeaders(marshalled, Optional.of(requestBody.contentLength()), requiresLength, transferEncoding, useHttp2);
return marshalled.build();
}
private Region getRegion(final ProviderConfigurationContext configurationContext) {
final String regionValue = configurationContext.getProperties().get(REGION_PROP);
if (StringUtils.isBlank(regionValue)) {
throw new ProviderCreationException("The property '" + REGION_PROP + "' must be provided");
}
Region region = null;
for (Region r : Region.regions()) {
if (r.id().equals(regionValue)) {
region = r;
break;
}
}
if (region == null) {
LOGGER.warn("The provided region was not found in the list of known regions. This may indicate an invalid region, " +
"or may indicate a region that is newer than the known list of regions");
region = Region.of(regionValue);
}
LOGGER.debug("Using region {}", new Object[] {region.id()});
return region;
}
private void validateProxyEndpoint(String extension, URI endpoint, String clientType) {
if (StringUtils.isBlank(endpoint.getScheme())) {
throw new RuntimeConfigurationError(
String.format("quarkus.%s.%s-client.proxy.endpoint (%s) - scheme must be specified",
extension, clientType, endpoint.toString()));
}
if (StringUtils.isBlank(endpoint.getHost())) {
throw new RuntimeConfigurationError(
String.format("quarkus.%s.%s-client.proxy.endpoint (%s) - host must be specified",
extension, clientType, endpoint.toString()));
}
if (StringUtils.isNotBlank(endpoint.getUserInfo())) {
throw new RuntimeConfigurationError(
String.format("quarkus.%s.%s-client.proxy.endpoint (%s) - user info is not supported.",
extension, clientType, endpoint.toString()));
}
if (StringUtils.isNotBlank(endpoint.getPath())) {
throw new RuntimeConfigurationError(
String.format("quarkus.%s.%s-client.proxy.endpoint (%s) - path is not supported.",
extension, clientType, endpoint.toString()));
}
if (StringUtils.isNotBlank(endpoint.getQuery())) {
throw new RuntimeConfigurationError(
String.format("quarkus.%s.%s-client.proxy.endpoint (%s) - query is not supported.",
extension, clientType, endpoint.toString()));
}
if (StringUtils.isNotBlank(endpoint.getFragment())) {
throw new RuntimeConfigurationError(
String.format("quarkus.%s.%s-client.proxy.endpoint (%s) - fragment is not supported.",
extension, clientType, endpoint.toString()));
}
}
private void validateFileContentMatches(File outputFile, String newFileContents) throws IOException {
byte[] currentFileBytes = Files.readAllBytes(outputFile.toPath());
String currentFileContents = new String(currentFileBytes, StandardCharsets.UTF_8);
String currentContentForComparison = codeComparisonTransformer.apply(currentFileContents);
String newContentForComparison = codeComparisonTransformer.apply(newFileContents);
if (!StringUtils.equals(currentContentForComparison, newContentForComparison)) {
throw new IllegalStateException("Attempted to clobber existing file (" + outputFile + ") with a new file that has " +
"different content. This may indicate forgetting to clean up old generated files " +
"before running the generator?\n" +
"Existing file: \n" + currentContentForComparison + "\n\n" +
"New file: \n" + newContentForComparison);
}
}
public static String capitalize(String name) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Name cannot be null or empty");
}
return name.length() < 2 ? StringUtils.upperCase(name) : StringUtils.upperCase(name.substring(0, 1))
+ name.substring(1);
}
private String standardizeProtocol(String protocol) {
Validate.paramNotNull(protocol, "protocol");
String standardizedProtocol = StringUtils.lowerCase(protocol);
Validate.isTrue(standardizedProtocol.equals("http") || standardizedProtocol.equals("https"),
"Protocol must be 'http' or 'https', but was %s", protocol);
return standardizedProtocol;
}
/**
* Returns true if the specified port is the standard port for the given protocol. (i.e. 80 for HTTP or 443 for HTTPS).
*
* Null or -1 ports (to simplify interaction with {@link URI}'s default value) are treated as standard ports.
*
* @return True if the specified port is standard for the specified protocol, otherwise false.
*/
public static boolean isUsingStandardPort(String protocol, Integer port) {
Validate.paramNotNull(protocol, "protocol");
Validate.isTrue(protocol.equals("http") || protocol.equals("https"),
"Protocol must be 'http' or 'https', but was '%s'.", protocol);
String scheme = StringUtils.lowerCase(protocol);
return port == null || port == -1 ||
(scheme.equals("http") && port == 80) ||
(scheme.equals("https") && port == 443);
}
/**
* Append the given path to the given baseUri, separating them with a slash, if required. The result will preserve the
* trailing slash of the provided path.
*/
public static String appendUri(String baseUri, String path) {
Validate.paramNotNull(baseUri, "baseUri");
StringBuilder resultUri = new StringBuilder(baseUri);
if (!StringUtils.isEmpty(path)) {
if (!baseUri.endsWith("/")) {
resultUri.append("/");
}
resultUri.append(path.startsWith("/") ? path.substring(1) : path);
}
return resultUri.toString();
}
/**
* Parse the account ID out of the IAM user arn
*
* @param arn IAM user ARN
* @return Account ID if it can be extracted
* @throws IllegalArgumentException If ARN is not in a valid format
*/
private String parseAccountIdFromArn(String arn) throws IllegalArgumentException {
String[] arnComponents = arn.split(":");
if (arnComponents.length < 5 || StringUtils.isEmpty(arnComponents[4])) {
throw new IllegalArgumentException(String.format("%s is not a valid ARN", arn));
}
return arnComponents[4];
}
@Override
public Optional<Boolean> resolveUseArnRegion() {
return profileFile.get()
.profile(profileName)
.map(p -> p.properties().get(AWS_USE_ARN_REGION))
.map(StringUtils::safeStringToBoolean);
}
private static String encodedPathAndQueryParams(SdkHttpRequest sdkRequest) {
String encodedPath = sdkRequest.encodedPath();
if (StringUtils.isBlank(encodedPath)) {
encodedPath = "/";
}
String encodedQueryParams = SdkHttpUtils.encodeAndFlattenQueryParameters(sdkRequest.rawQueryParameters())
.map(queryParams -> "?" + queryParams)
.orElse("");
return encodedPath + encodedQueryParams;
}
private SslHandler createSslHandlerIfNeeded(ByteBufAllocator alloc) {
if (sslContext == null) {
return null;
}
String scheme = proxyAddress.getScheme();
if (!"https".equals(StringUtils.lowerCase(scheme))) {
return null;
}
return sslContext.newHandler(alloc, proxyAddress.getHost(), proxyAddress.getPort());
}
/**
* Returns the Java system property for nonProxyHosts as set of Strings.
* See http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html.
*/
private Set<String> parseNonProxyHostsProperty() {
String nonProxyHosts = ProxySystemSetting.NON_PROXY_HOSTS.getStringValue().orElse(null);
if (!StringUtils.isEmpty(nonProxyHosts)) {
return Arrays.stream(nonProxyHosts.split("\\|"))
.map(String::toLowerCase)
.map(s -> s.replace("*", ".*?"))
.collect(Collectors.toSet());
}
return Collections.emptySet();
}
private List<NameValuePair> parseNameValuePairsFromQuery(LoggedRequest actual) {
String queryParams = URI.create(actual.getUrl()).getQuery();
if (StringUtils.isEmpty(queryParams)) {
return Collections.emptyList();
}
return URLEncodedUtils.parse(queryParams, StandardCharsets.UTF_8);
}
private String getMethodName(MemberModel memberModel) {
String methodName = StringUtils.uncapitalize(memberModel.getName());
if (Utils.isListWithEnumShape(memberModel) || Utils.isMapWithEnumShape(memberModel)) {
methodName += "WithStrings";
}
return methodName;
}
protected FieldSpec operationInfoField() {
CodeBlock.Builder initializationCodeBlockBuilder = CodeBlock.builder()
.add("$T.builder()", OperationInfo.class);
initializationCodeBlockBuilder.add(".requestUri($S)", shapeModel.getMarshaller().getRequestUri())
.add(".httpMethod($T.$L)", SdkHttpMethod.class, shapeModel.getMarshaller().getVerb())
.add(".hasExplicitPayloadMember($L)", shapeModel.isHasPayloadMember() ||
shapeModel.getExplicitEventPayloadMember() != null)
.add(".hasPayloadMembers($L)", shapeModel.hasPayloadMembers());
if (StringUtils.isNotBlank(shapeModel.getMarshaller().getTarget())) {
initializationCodeBlockBuilder.add(".operationIdentifier($S)", shapeModel.getMarshaller().getTarget());
}
if (shapeModel.isHasStreamingMember()) {
initializationCodeBlockBuilder.add(".hasStreamingInput(true)");
}
if (isEventStreamParentModel(shapeModel)) {
initializationCodeBlockBuilder.add(".hasEventStreamingInput(true)");
}
CodeBlock codeBlock = initializationCodeBlockBuilder.add(".build()").build();
return FieldSpec.builder(ClassName.get(OperationInfo.class), "SDK_OPERATION_BINDING")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL, Modifier.STATIC)
.initializer(codeBlock)
.build();
}
@Override
public List<FieldSpec> memberVariables() {
List<FieldSpec> fields = new ArrayList<>();
CodeBlock.Builder initializationCodeBlockBuilder = CodeBlock.builder()
.add("$T.builder()", OperationInfo.class);
initializationCodeBlockBuilder.add(".requestUri($S)", shapeModel.getMarshaller().getRequestUri())
.add(".httpMethod($T.$L)", SdkHttpMethod.class, shapeModel.getMarshaller().getVerb())
.add(".hasExplicitPayloadMember($L)", shapeModel.isHasPayloadMember() ||
shapeModel.getExplicitEventPayloadMember() != null)
.add(".hasPayloadMembers($L)", shapeModel.hasPayloadMembers());
if (StringUtils.isNotBlank(shapeModel.getMarshaller().getTarget())) {
initializationCodeBlockBuilder.add(".operationIdentifier($S)", shapeModel.getMarshaller().getTarget())
.add(".apiVersion($S)", metadata.getApiVersion());
}
if (shapeModel.isHasStreamingMember()) {
initializationCodeBlockBuilder.add(".hasStreamingInput(true)");
}
if (metadata.getProtocol() == Protocol.REST_XML) {
String rootMarshallLocationName = shapeModel.getMarshaller() != null ?
shapeModel.getMarshaller().getLocationName() : null;
initializationCodeBlockBuilder.add(".putAdditionalMetadata($T.ROOT_MARSHALL_LOCATION_ATTRIBUTE, $S)",
AwsXmlProtocolFactory.class, rootMarshallLocationName);
initializationCodeBlockBuilder.add(".putAdditionalMetadata($T.XML_NAMESPACE_ATTRIBUTE, $S)",
AwsXmlProtocolFactory.class, xmlNameSpaceUri());
}
CodeBlock codeBlock = initializationCodeBlockBuilder.add(".build()").build();
FieldSpec.Builder instance = FieldSpec.builder(ClassName.get(OperationInfo.class), "SDK_OPERATION_BINDING")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL, Modifier.STATIC)
.initializer(codeBlock);
fields.add(instance.build());
fields.add(protocolFactory());
return fields;
}