Skip to content
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

Adding validation rules for subscriptionId/api-version params #1513

Merged
merged 8 commits into from
Oct 20, 2016

Conversation

dsgouda
Copy link
Contributor

@dsgouda dsgouda commented Oct 17, 2016

Adding validation rules to enforce:

  • Parameters section for operations should not define the subscriptionId and api-version parameters
  • Service definition section must contain parameters api-version and subscriptionId

Modified all swagger validation test jsons to adhere to these validation rules
Fixing issue #1515

@tbombach

@fearthecowboy
Copy link
Member

fearthecowboy commented Oct 18, 2016

If you're changing JSON files, make sure you pull all the latest code and do a gulp regenerate:expected test and then add in any changed files with a separate commit message 👍 #Resolved

@@ -252,4 +252,10 @@
<data name="InvalidConstraint" xml:space="preserve">
<value>Constraint is not supported for this type and will be ignored.</value>
</data>
<data name="OperationParametersNotAllowedMessage" xml:space="preserve">
<value>Parameters "subscriptionId" and "api-version" are not allowed in the operations section of azure swagger specs</value>
Copy link
Member

@fearthecowboy fearthecowboy Oct 18, 2016

Choose a reason for hiding this comment

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

Parameters "subscriptionId" and "api-version" are not allowed in the operations section ? #Resolved

/// <returns></returns>
public override bool IsValid(Dictionary<string, SwaggerParameter> ParametersMap)
{
if (ParametersMap.Count==0 || ParametersMap == null)
Copy link
Member

Choose a reason for hiding this comment

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

Braces please. 😀

if (ParametersMap.Count==0 || ParametersMap == null)
{
    return false;
}

return false;

var Names = ParametersMap.Values.Select(Param => Param.Name).ToList();
return Names.Contains(SubscriptionId) && Names.Contains(ApiVersion);
Copy link
Member

Choose a reason for hiding this comment

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

The code

var Names = ParametersMap.Values.Select(Param => Param.Name).ToList();
return Names.Contains(SubscriptionId) && Names.Contains(ApiVersion);

is iterating the ParametersMap.Values enumerable and allocating a List for no benefit.
.ToList() should be reserved for when you actually need to manipulate the result set of an enumeration.

The following will iterate the set only once, and will return at the first true case. If there are a 1000 items in the list, and the first is matched, the iterating stops there. The happy path is the fast path ⏩

return ParametersMap.Values.Any( parameter => parameter.Name == SubscriptionId  || parameter.Name == ApiVersion );

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This helps my limited knowledge of Linq 😄

/// <returns></returns>
public override bool IsValid(Dictionary<string, SwaggerParameter> ParametersMap)
{
if (ParametersMap.Count==0 || ParametersMap == null)
Copy link
Member

Choose a reason for hiding this comment

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

Actually, you don't want to check the count; that presumes either that the dictionary implementation knows the actual item count (which not all do), or you're forcing the dictionary to count the items. The iteration below will be nearly 0 time if the collection is empty anyway.

So replace this with

if( ParametersMap == null ) 
{ 
    return false;
}


var Names = ParametersMap.Values.Select(Param => Param.Name).ToList();
return Names.Contains(SubscriptionId) && Names.Contains(ApiVersion);
}
Copy link
Member

@fearthecowboy fearthecowboy Oct 18, 2016

Choose a reason for hiding this comment

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

Now, I get to the bottom and see that you could simplify it a bit more, and use a single expression that leverages null-propagation operator (which turns the expression result into a nullable bool result bool? which can be trivially coaxed back into a bool by adding true == at the front of the expression.

  public override bool IsValid(Dictionary<string, SwaggerParameter> ParametersMap) => 
    true == ParametersMap?.Values.Any( parameter => parameter.Name == SubscriptionId  || parameter.Name == ApiVersion );

/// <param name="paths"></param>
/// <returns></returns>
public override bool IsValid(SwaggerParameter Parameter)
{
Copy link
Member

Choose a reason for hiding this comment

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

rather than performing the separate checks on the Parameter and Parameter.Name, you can use the null-propagation operator to fold it into a single check and let the compiler to the heavy lifting.

public override bool IsValid(SwaggerParameter Parameter) => 
    SubscriptionId  != Parameter?.Name && 
    ApiVersion != Parameter?.Name;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

New concepts, taking 🗒

@fearthecowboy
Copy link
Member

LGTM 👍

@dsgouda
Copy link
Contributor Author

dsgouda commented Oct 19, 2016

@azuresdkci retest this please

@dsgouda dsgouda merged commit e67ca8d into Azure:master Oct 20, 2016
@dsgouda dsgouda deleted the params branch October 28, 2016 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants