Skip to content

Phase 2 final operations #3949

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions generator/.DevConfigs/79b46eff-9dd1-4281-88f0-22c700a96506.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"core": {
"updateMinimum": true,
"type": "patch",
"changeLogMessages": [
"Remove extra Content MD5 setting in BaseMarshaller. Minor Xml namespace logic updates. Update all rest-xml service response unmarshallers to generate partial method PostUnmarshallCustomization. Generator updates."
]
},
"services": [
{
"serviceName": "S3",
"type": "patch",
"changeLogMessages": [
"Generate PutBucketAcl PutBucketCors,PutObjectAcl, GetObjectAcl, ListObjectsV2, ListVersions, HeadObject.",
"As part of generating S3, all response unmarshallers will implement UnmarshallException. GetObjectACL will now throw NoSuchKeyException if no such key exists. This is not a breaking change."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could this cause issues for customers if they are catching UnmarshalException in their code and not handling NoSuchKey?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So a customer right now would be catching the generic AmazonS3Exception which will still work because NoSuchKeyException inherits AmazonS3Exception. So, not a breaking change.

]
}
]
}
100 changes: 96 additions & 4 deletions generator/ServiceClientGeneratorLib/Customizations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,20 @@ public PropertyModifier GetPropertyModifier(string shapeName, string propertyNam
return null;
}

/// <summary>
/// Gets the property modifier for a property if it exists. Otherwise returns false.
/// </summary>
/// <param name="shapeName"></param>
/// <param name="propertyName"></param>
/// <param name="propertyModifier"></param>
/// <returns></returns>
public bool TryGetPropertyModifier(string shapeName, string propertyName, out PropertyModifier propertyModifier)
{
propertyModifier = null;
propertyModifier = GetPropertyModifier(shapeName, propertyName) ?? null;
return propertyModifier != null ? true : false;
}

/// <summary>
/// Determines if the property has a customization to be set to nullable
/// </summary>
Expand Down Expand Up @@ -1020,6 +1034,7 @@ public class ShapeModifier
public const string ShapeModifierXmlNamespaceKey = "xmlNamespace";
public const string OriginalMemberIsOutsideContainingShapeKey = "originalMemberIsOutsideContainingShape";
public const string PredicateListUnmarshallersKey = "predicateListUnmarshallers";
public const string ExcludeFromUnmarshallingKey = "excludeFromUnmarshalling";

private readonly HashSet<string> _excludedProperties;
private readonly Dictionary<string, JsonData> _modifiedProperties;
Expand All @@ -1030,6 +1045,7 @@ public class ShapeModifier
private readonly HashSet<string> _shapeDocumentation;
private readonly string _shapeModifierXmlNamespace;
private readonly Dictionary<string, JsonData> _predicateListUnmarshallers;
private readonly HashSet<string> _excludedUnmarshallingProperties;

public string DeprecationMessage { get; private set; }

Expand All @@ -1049,6 +1065,7 @@ public ShapeModifier(JsonData data)
_shapeDocumentation = ParseShapeDocumentation(data);
_shapeModifierXmlNamespace = ParseXmlNamespace(data);
_predicateListUnmarshallers = ParsePredicateListUnmarshallers(data);
_excludedUnmarshallingProperties = ParseExcludedUnmarshallingProperties(data);
Validate(data);
}

Expand Down Expand Up @@ -1317,6 +1334,7 @@ private static Dictionary<string, JsonData> ParsePredicateListUnmarshallers(Json
?? new Dictionary<string, JsonData>();

}

/// <summary>
/// This customization tells the generator that the member's shape is a filter type that has predicates
/// and operators and that it should be unmarshalled with the PredicateListUnmarshaller type that each
Expand All @@ -1327,6 +1345,35 @@ private static Dictionary<string, JsonData> ParsePredicateListUnmarshallers(Json
public Dictionary<string, JsonData> PredicateListUnmarshallers { get { return _predicateListUnmarshallers; } }

#endregion

#region ExcludedUnmarshallingProperties

private static HashSet<string> ParseExcludedUnmarshallingProperties(JsonData data)
{
var excludedUnmarshallingProperties = data[ShapeModifier.ExcludeFromUnmarshallingKey]?.Cast<object>()
.Select(x => x.ToString());

return new HashSet<string>(excludedUnmarshallingProperties ?? new string[0]);
}

/// <summary>
/// Properties that should be excluded from unmarshalling. Example usage:
///
/// The members that should be excluded are in the array.
/// "S3Grantee":{
/// "modify": [
/// {
/// "ID": {"emitPropertyName": "CanonicalUser"}
/// }
/// ],
/// "excludeFromUnmarshalling":
/// [
/// "Type"
/// ]
/// },
/// </summary>
public HashSet<string> ExcludedUnmarshallingProperties { get { return _excludedUnmarshallingProperties; } }
#endregion
}

/// <summary>
Expand Down Expand Up @@ -1393,14 +1440,17 @@ public class PropertyModifier
public const string EmitPropertyNameKey = "emitPropertyName";
public const string LocationNameKey = "locationName";
public const string AccessModifierKey = "accessModifier";
public const string InjectXmlUnmarshallCodeKey = "injectXmlUnmarshallCode";
public const string SkipContextTestExpressionUnmarshallingLogicKey = "skipContextTestExpressionUnmarshallingLogic";

private readonly string _modelPropertyName; // for debug inspection assist
private readonly JsonData _modifierData;

private readonly HashSet<string> _injectXmlUnmarshallCode;
internal PropertyModifier(string modelPropertyName, JsonData modifierData)
{
this._modelPropertyName = modelPropertyName;
this._modifierData = modifierData;
_injectXmlUnmarshallCode = ParseInjectXmlUnmarshallCode();
}

// The access modifier for the property. Defaults to public if not set in the customization.
Expand Down Expand Up @@ -1473,14 +1523,56 @@ public bool UseCustomMarshall
}

public string DeprecationMessage
{
get
{
get
{
return _modifierData[ShapeModifier.DeprecatedMessageKey].CastToString();
}
}
}

private HashSet<string> ParseInjectXmlUnmarshallCode()
{
var data = _modifierData[InjectXmlUnmarshallCodeKey]?.Cast<object>()
.Select(x => x.ToString());

return new HashSet<string>(data ?? new string[0]);
}

/// <summary>
/// Use this customization for rest-xml services when you want to inject some code into the "Context.TestExpression" portion
/// of the member.
///
/// A prime example of this is here https://github.com/aws/aws-sdk-net/blob/79cbc392fc3f1c74fcdf34efd77ad681da8af328/sdk/src/Services/S3/Custom/Model/Internal/MarshallTransformations/ListObjectsV2ResponseUnmarshaller.cs#L85
/// How to use this customization (within the modify array of a property) :
/// Within the "Contents" member while this member is being unmarshalled the code in the "injectXmlUnmarshallCode" will be added line by line
/// right before the "continue" statement within each "context.TestExpression" call.
/// {
/// "Contents" : {
/// "emitPropertyName" : "S3Objects",
/// "injectXmlUnmarshallCode":[
/// "response.S3Objects[response.S3Objects.Count - 1].BucketName = response.Name;"
/// ]
/// }
/// },
/// </summary>
public HashSet<string> InjectXmlUnmarshallCode
{
get { return _injectXmlUnmarshallCode; }
}

/// <summary>
/// If this is set, all the logic inside of the "context.testExpression" code block for that member won't be generated. this is meant
/// to be used in conjunction with InjectXmlUnmarshallCode, but can be used separately as well. For example:
/// "Versions":{
/// "skipContextTestExpressionUnmarshallingLogic" : true,
/// "injectXmlUnmarshallCode" :[
/// "VersionsItemCustomUnmarshall(context, response);"
/// ]
/// }
/// </summary>
public bool SkipContextTestExpressionUnmarshallingLogic { get { return _modifierData[SkipContextTestExpressionUnmarshallingLogicKey] != null; } }
}

#endregion
// Injection modifier is an array of objects, each object being the
private Dictionary<string, ShapeModifier> _shapeModifiers = null;
Expand Down
Loading