From d41bb32b3e2c6d4681ded1191bbc3a0a168dc230 Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Thu, 26 Sep 2019 17:11:29 -0700 Subject: [PATCH 01/14] [Storage] Change AccountInfo class to struct --- .../src/Generated/BlobRestClient.cs | 13 +++++--- .../Azure.Storage.Blobs/swagger/readme.md | 3 +- .../src/Azure.Storage.Common.csproj | 1 + .../swagger/Generator/src/generator.ts | 31 +++++++++++++++++-- .../swagger/Generator/src/models.ts | 6 ++-- .../swagger/Generator/src/serviceModel.ts | 16 +++++++++- 6 files changed, 59 insertions(+), 11 deletions(-) diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index f2a40ba643084..8ace4d6b21708 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -12788,23 +12788,28 @@ namespace Azure.Storage.Blobs.Models /// /// AccountInfo /// - public partial class AccountInfo + public partial struct AccountInfo { /// /// Identifies the sku name of the account /// - public Azure.Storage.Blobs.Models.SkuName SkuName { get; internal set; } + public Azure.Storage.Blobs.Models.SkuName SkuName { get; } /// /// Identifies the account kind /// - public Azure.Storage.Blobs.Models.AccountKind AccountKind { get; internal set; } + public Azure.Storage.Blobs.Models.AccountKind AccountKind { get; } /// /// Prevent direct instantiation of AccountInfo instances. /// You can use BlobsModelFactory.AccountInfo instead. /// - internal AccountInfo() { } + internal AccountInfo( + Azure.Storage.Blobs.Models.SkuName skuName, + Azure.Storage.Blobs.Models.AccountKind accountKind){ + SkuName = skuName; + AccountKind = accountKind; + } } /// diff --git a/sdk/storage/Azure.Storage.Blobs/swagger/readme.md b/sdk/storage/Azure.Storage.Blobs/swagger/readme.md index e568579894806..d3f9404b35a5d 100644 --- a/sdk/storage/Azure.Storage.Blobs/swagger/readme.md +++ b/sdk/storage/Azure.Storage.Blobs/swagger/readme.md @@ -222,6 +222,7 @@ directive: transform: > $.get.description = "Returns the sku name and account kind"; $.get.responses["200"]["x-az-response-name"] = "AccountInfo"; + $.get.responses["200"]["x-az-struct"] = true; - from: swagger-document where: $["x-ms-paths"] transform: > @@ -1065,4 +1066,4 @@ directive: where: $.parameters.PremiumPageBlobAccessTierOptional transform: > $["x-ms-enum"].name = "AccessTier"; -``` \ No newline at end of file +``` diff --git a/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj b/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj index 8c9e0d4e430f8..4a06440cb57ab 100644 --- a/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj +++ b/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj @@ -24,5 +24,6 @@ --> + diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index e7b96c3a9b204..6d19765623214 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -841,7 +841,8 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`/// ${type.description || type.name}`); w.line(`/// `); if (type.disableWarnings) { w.line(`#pragma warning disable ${type.disableWarnings}`); } - w.line(`${type.public ? 'public' : 'internal'} partial class ${naming.type(type.name)}`); + if (type.struct) { w.line(`${type.public ? 'public' : 'internal'} partial struct ${naming.type(type.name)}`); } + else { w.line(`${type.public ? 'public' : 'internal'} partial class ${naming.type(type.name)}`); } if (type.disableWarnings) { w.line(`#pragma warning restore ${type.disableWarnings}`); } const separator = IndentWriter.createFenceposter(); w.scope('{', '}', () => { @@ -854,10 +855,14 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`#pragma warning disable CA1819 // Properties should not return arrays`); } w.write(`public ${types.getDeclarationType(property.model, property.required, property.readonly)} ${naming.property(property.clientName)} { get; `); + if (!type.struct){ if (property.readonly || property.model.type === `array`) { w.write(`internal `); } - w.line(`set; }`); + w.write(`set; `); + } + w.write(`}`); + w.line(); if (property.model.type === `byte`) { w.line(`#pragma warning restore CA1819 // Properties should not return arrays`); } @@ -913,7 +918,27 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`/// Prevent direct instantiation of ${naming.type(type.name)} instances.`); w.line(`/// You can use ${factoryName}.${naming.type(type.name)} instead.`); w.line(`/// `); - w.line(`internal ${naming.type(type.name)}() { }`); + if(type.struct) { + const properties = Object.values(type.properties); + w.write(`internal ${naming.type(type.name)}(`); + w.scope(() => { + const separator = IndentWriter.createFenceposter(); + // Sort `= default` parameters last + properties.sort((a: IProperty, b: IProperty) => a.required ? -1 : b.required ? 1 : 0); + for (const property of properties) { + if (separator()) { w.line(`,`); } + w.write(`${types.getDeclarationType(property.model, property.required, property.readonly)} ${naming.parameter(property.clientName)}`); + if (!property.required) { w.write(` = default`); } + } + w.write(`)`); + w.scope('{', '}', () => { + for (const property of properties) { + w.line(`${naming.property(property.clientName)} = ${naming.parameter(property.clientName)};`); + } + }); + }); + } + else { w.line(`internal ${naming.type(type.name)}() { }`); } } // Create serializers if necessary diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/models.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/models.ts index ca4253bbb93c0..987ee83ee7107 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/models.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/models.ts @@ -133,7 +133,8 @@ export interface IObjectType extends IModelType { serialize: boolean, deserialize: boolean, disableWarnings?: string, - public: boolean + public: boolean, + struct: boolean } export function isObjectType(model: IModelType): model is IObjectType { @@ -237,7 +238,8 @@ export interface IResponse { model?: IModelType, exception?: boolean, public: boolean, - returnStream?: boolean + returnStream?: boolean, + struct: boolean } export interface IResponseGroup { diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/serviceModel.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/serviceModel.ts index 8016cfc49048c..9c931978fc94b 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/serviceModel.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/serviceModel.ts @@ -428,6 +428,11 @@ function createObjectType(project: IProject, name: string, swagger: any, locatio isPublic = true; } + let isStruct: boolean|undefined = swagger[`x-az-struct`]; + if (isStruct === undefined) { + isStruct = false; + } + const info = required(() => project.cache.info); return { type: `object`, @@ -441,6 +446,7 @@ function createObjectType(project: IProject, name: string, swagger: any, locatio deserialize: false, disableWarnings: swagger[`x-az-disable-warnings`], public: isPublic, + struct: isStruct, extendedHeaders: [] }; } @@ -602,6 +608,11 @@ function createResponse(project: IProject, code: string, name: string, swagger: isPublic = true; } + let isStruct: boolean|undefined = swagger[`x-az-struct`]; + if (isStruct === undefined) { + isStruct = false; + } + return { code, description: swagger.description, @@ -611,6 +622,7 @@ function createResponse(project: IProject, code: string, name: string, swagger: headers, exception: optional(() => swagger[`x-az-create-exception`]), public: isPublic, + struct: isStruct, returnStream: optional(() => swagger[`x-az-stream`]) }; } @@ -944,6 +956,7 @@ function getOperationResponse(project: IProject, responses: IResponses, defaultN name: response.clientName || defaultName, namespace: `${info.namespace}.Models`, public: response.public, + struct: response.struct, properties: { }, serialize: false, deserialize: false, @@ -996,7 +1009,8 @@ function getOperationResponse(project: IProject, responses: IResponses, defaultN body: a.body || b.body, bodyClientName: a.bodyClientName || b.bodyClientName, headers: { ...b.headers, ...a.headers }, - public: a.public && b.public + public: a.public && b.public, + struct: a.struct && b.struct }; } } From e284aa41f3be9ffeeb12121659105ba63259d623 Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Fri, 27 Sep 2019 11:09:39 -0700 Subject: [PATCH 02/14] serialization and deserialization --- .../src/Generated/BlobRestClient.cs | 17 +++-- .../swagger/Generator/src/generator.ts | 64 ++++++++++++++----- .../swagger/Generator/src/serviceModel.ts | 12 ++-- sdk/storage/generate.ps1 | 4 +- 4 files changed, 65 insertions(+), 32 deletions(-) diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index 8ace4d6b21708..0b3bc31456511 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -835,20 +835,23 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage GetAccountInfoAsync_Crea { case 200: { - // Create the result - Azure.Storage.Blobs.Models.AccountInfo _value = new Azure.Storage.Blobs.Models.AccountInfo(); // Get response headers string _header; + Azure.Storage.Blobs.Models.SkuName skuName = default; + Azure.Storage.Blobs.Models.AccountKind accountKind = default; if (response.Headers.TryGetValue("x-ms-sku-name", out _header)) { - _value.SkuName = Azure.Storage.Blobs.BlobRestClient.Serialization.ParseSkuName(_header); + skuName = Azure.Storage.Blobs.BlobRestClient.Serialization.ParseSkuName(_header); } if (response.Headers.TryGetValue("x-ms-account-kind", out _header)) { - _value.AccountKind = (Azure.Storage.Blobs.Models.AccountKind)System.Enum.Parse(typeof(Azure.Storage.Blobs.Models.AccountKind), _header, false); + accountKind = (Azure.Storage.Blobs.Models.AccountKind)System.Enum.Parse(typeof(Azure.Storage.Blobs.Models.AccountKind), _header, false); } + // Create the result + Azure.Storage.Blobs.Models.AccountInfo _value = new Azure.Storage.Blobs.Models.AccountInfo(skuName, accountKind); + // Create the response Azure.Response _result = new Azure.Response( @@ -12824,11 +12827,7 @@ public static AccountInfo AccountInfo( Azure.Storage.Blobs.Models.SkuName skuName, Azure.Storage.Blobs.Models.AccountKind accountKind) { - return new AccountInfo() - { - SkuName = skuName, - AccountKind = accountKind, - }; + return new AccountInfo(skuName, accountKind); } } } diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index 6d19765623214..fba37cf45365d 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -507,7 +507,7 @@ function generateOperation(w: IndentWriter, serviceModel: IServiceModel, group: const model = response.model; // Deserialize - w.line(`// Create the result`); + if (!response.struct) w.line(`// Create the result`); if (response.body) { const responseType = response.body; if (responseType.type === `string`) { @@ -581,7 +581,7 @@ function generateOperation(w: IndentWriter, serviceModel: IServiceModel, group: } else { throw `Serialization format ${operation.produces} not supported (in ${name})`; } - } else { + } else if (!response.struct) { w.line(`${types.getName(model)} ${valueName} = new ${types.getName(model)}();`); } w.line(); @@ -590,6 +590,11 @@ function generateOperation(w: IndentWriter, serviceModel: IServiceModel, group: if (headers.length > 0) { w.line(`// Get response headers`); w.line(`string ${headerName};`); + if (response.struct) { + for (const header of headers) { + w.line(`${types.getDeclarationType(header.model, true, false, true)} ${naming.parameter(header.clientName)} = default;`); + } + } for (const header of headers) { if (isPrimitiveType(header.model) && header.model.type === 'dictionary') { const prefix = header.model.dictionaryPrefix || `x-ms-meta-`; @@ -604,7 +609,11 @@ function generateOperation(w: IndentWriter, serviceModel: IServiceModel, group: } else { w.line(`if (${responseName}.Headers.TryGetValue("${header.name}", out ${headerName}))`); w.scope('{', '}', () => { - w.write(`${valueName}.${naming.pascalCase(header.clientName)} = `); + if (response.struct) { + w.write(`${naming.parameter(header.clientName)} = `); + } else { + w.write(`${valueName}.${naming.pascalCase(header.clientName)} = `); + } if (isPrimitiveType(header.model) && header.model.collectionFormat === `csv`) { if (!header.model.itemType || header.model.itemType.type !== `string`) { throw `collectionFormat csv is only supported for strings, at the moment`; @@ -617,6 +626,18 @@ function generateOperation(w: IndentWriter, serviceModel: IServiceModel, group: }); } } + if (response.struct) { + w.line(); + w.line(`// Create the result`); + const Separator = IndentWriter.createFenceposter(); + w.write(`${types.getName(model)} ${valueName} = new ${types.getName(model)}(`); + for (const header of headers) { + if (Separator()) { w.write(`, `); } + w.write(`${naming.parameter(header.clientName)}`); + } + w.write(`);`); + w.line(); + } w.line(); } } @@ -855,11 +876,11 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`#pragma warning disable CA1819 // Properties should not return arrays`); } w.write(`public ${types.getDeclarationType(property.model, property.required, property.readonly)} ${naming.property(property.clientName)} { get; `); - if (!type.struct){ - if (property.readonly || property.model.type === `array`) { - w.write(`internal `); - } - w.write(`set; `); + if (!type.struct) { + if (property.readonly || property.model.type === `array`) { + w.write(`internal `); + } + w.write(`set; `); } w.write(`}`); w.line(); @@ -918,7 +939,7 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`/// Prevent direct instantiation of ${naming.type(type.name)} instances.`); w.line(`/// You can use ${factoryName}.${naming.type(type.name)} instead.`); w.line(`/// `); - if(type.struct) { + if (type.struct) { const properties = Object.values(type.properties); w.write(`internal ${naming.type(type.name)}(`); w.scope(() => { @@ -992,15 +1013,28 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType } w.write(`)`); }); - w.scope('{', '}', () => { - w.line(`return new ${typeName}()`); - - w.scope('{', '};', () => { + const separator = IndentWriter.createFenceposter(); + if (type.struct) { + w.scope('{', '}', () => { + w.write(`return new ${typeName}(`); for (const property of props) { - w.line(`${naming.property(property.clientName)} = ${naming.parameter(property.clientName)},`); + if (separator()) { w.write(`, `); } + w.write(`${naming.parameter(property.clientName)}`); + if (!property.required) { w.write(` = default`); } } + w.write(`);`); }); - }); + } else { + w.scope('{', '}', () => { + w.line(`return new ${typeName}()`); + + w.scope('{', '};', () => { + for (const property of props) { + w.line(`${naming.property(property.clientName)} = ${naming.parameter(property.clientName)},`); + } + }); + }); + } }); } }); diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/serviceModel.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/serviceModel.ts index 9c931978fc94b..f55c00ef127a6 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/serviceModel.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/serviceModel.ts @@ -446,8 +446,8 @@ function createObjectType(project: IProject, name: string, swagger: any, locatio deserialize: false, disableWarnings: swagger[`x-az-disable-warnings`], public: isPublic, - struct: isStruct, - extendedHeaders: [] + extendedHeaders: [], + struct: isStruct }; } @@ -622,8 +622,8 @@ function createResponse(project: IProject, code: string, name: string, swagger: headers, exception: optional(() => swagger[`x-az-create-exception`]), public: isPublic, - struct: isStruct, - returnStream: optional(() => swagger[`x-az-stream`]) + returnStream: optional(() => swagger[`x-az-stream`]), + struct: isStruct }; } @@ -956,11 +956,11 @@ function getOperationResponse(project: IProject, responses: IResponses, defaultN name: response.clientName || defaultName, namespace: `${info.namespace}.Models`, public: response.public, - struct: response.struct, properties: { }, serialize: false, deserialize: false, - extendedHeaders: ignoredHeaders + extendedHeaders: ignoredHeaders, + struct: response.struct }; registerCustomType(project, model); diff --git a/sdk/storage/generate.ps1 b/sdk/storage/generate.ps1 index 8a8241c744588..dc0946e92872b 100644 --- a/sdk/storage/generate.ps1 +++ b/sdk/storage/generate.ps1 @@ -10,7 +10,7 @@ autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose cd $PSScriptRoot/Azure.Storage.Queues/swagger/ autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose -cd $PSScriptRoot/Azure.Storage.Files.DataLake/swagger/ -autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose +# cd $PSScriptRoot/Azure.Storage.Files.DataLake/swagger/ +# autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose popd From 669d84901b6d7dc5872494700206ed62cebf37eb Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Fri, 27 Sep 2019 13:44:46 -0700 Subject: [PATCH 03/14] Add equals and hashcode methods --- .../src/Generated/BlobRestClient.cs | 39 +++++++++++++++++-- .../swagger/Generator/src/generator.ts | 39 ++++++++++++++++++- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index 0b3bc31456511..42014e2e4dc80 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -12785,13 +12785,13 @@ public partial struct AccessTier : System.IEquatable } #endregion enum strings AccessTier -#region class AccountInfo +#region struct AccountInfo namespace Azure.Storage.Blobs.Models { /// /// AccountInfo /// - public partial struct AccountInfo + public readonly partial struct AccountInfo: System.IEquatable { /// /// Identifies the sku name of the account @@ -12813,6 +12813,39 @@ internal AccountInfo( SkuName = skuName; AccountKind = accountKind; } + + /// + /// Check if two AccountInfo instances are equal. + /// + /// The instance to compare to. + /// True if they're equal, false otherwise. + public bool Equals(AccountInfo other) + { + if (!SkuName.Equals(other.SkuName)) + return false; + if (!AccountKind.Equals(other.AccountKind)) + return false; + + return true; + } + + /// + /// Check if two AccountInfo instances are equal. + /// + /// The instance to compare to. + /// True if they're equal, false otherwise. + public override bool Equals(object obj) => obj is AccountInfo && Equals((AccountInfo)obj); + + /// + /// Get a hash code for the AccountInfo. + /// + public override int GetHashCode(){ + var hashCode = new Azure.Core.HashCodeBuilder(); + hashCode.Add(SkuName); + hashCode.Add(AccountKind); + + return hashCode.ToHashCode(); + } } /// @@ -12831,7 +12864,7 @@ public static AccountInfo AccountInfo( } } } -#endregion class AccountInfo +#endregion struct AccountInfo #region enum AccountKind namespace Azure.Storage.Blobs.Models diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index fba37cf45365d..59c45ca744ea3 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -854,7 +854,7 @@ function generateEnumStrings(w: IndentWriter, model: IServiceModel, type: IEnumT function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType) { const service = model.service; - const regionName = `class ${naming.type(type.name)}`; + const regionName = type.struct ? `struct ${naming.type(type.name)}` : `class ${naming.type(type.name)}`; w.line(`#region ${regionName}`); w.line(`namespace ${naming.namespace(type.namespace)}`); w.scope('{', '}', () => { @@ -862,7 +862,7 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`/// ${type.description || type.name}`); w.line(`/// `); if (type.disableWarnings) { w.line(`#pragma warning disable ${type.disableWarnings}`); } - if (type.struct) { w.line(`${type.public ? 'public' : 'internal'} partial struct ${naming.type(type.name)}`); } + if (type.struct) { w.line(`${type.public ? 'public' : 'internal'} readonly partial struct ${naming.type(type.name)}: System.IEquatable<${naming.type(type.name)}>`); } else { w.line(`${type.public ? 'public' : 'internal'} partial class ${naming.type(type.name)}`); } if (type.disableWarnings) { w.line(`#pragma warning restore ${type.disableWarnings}`); } const separator = IndentWriter.createFenceposter(); @@ -958,6 +958,41 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType } }); }); + w.line(); + w.line(`/// `) + w.line(`/// Check if two ${naming.type(type.name)} instances are equal.`); + w.line(`/// `); + w.line(`/// The instance to compare to.`); + w.line(`/// True if they're equal, false otherwise.`); + w.line(`public bool Equals(${naming.type(type.name)} other)`); + w.scope('{', '}', () => { + for (const property of properties) { + w.line(`if (!${naming.property(property.clientName)}.Equals(other.${naming.property(property.clientName)}))`); + w.line(` return false;`); + } + w.line(); + w.line(`return true;`); + }); + w.line(); + w.line(`/// `); + w.line(`/// Check if two ${naming.type(type.name)} instances are equal.`); + w.line(`/// `); + w.line(`/// The instance to compare to.`); + w.line(`/// True if they're equal, false otherwise.`); + w.line(`public override bool Equals(object obj) => obj is ${naming.type(type.name)} && Equals((${naming.type(type.name)})obj);`); + w.line(); + w.line(`/// `) + w.line(`/// Get a hash code for the AccountInfo.`); + w.line(`/// `); + w.write(`public override int GetHashCode()`); + w.scope('{', '}', () => { + w.line(`var hashCode = new Azure.Core.HashCodeBuilder();`); + for (const property of properties) { + w.line(`hashCode.Add(${naming.property(property.clientName)});`); + } + w.line(); + w.line(`return hashCode.ToHashCode();`); + }); } else { w.line(`internal ${naming.type(type.name)}() { }`); } } From 583648c749146cd8452ed0aa5de222e981dacd43 Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Fri, 27 Sep 2019 18:26:57 -0700 Subject: [PATCH 04/14] Chnage PageInfo class to model --- .../src/Generated/BlobRestClient.cs | 159 +++++++++++++----- .../Azure.Storage.Blobs/swagger/readme.md | 8 + .../swagger/Generator/src/generator.ts | 6 +- 3 files changed, 130 insertions(+), 43 deletions(-) diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index 42014e2e4dc80..fc70fea542a2e 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -7817,36 +7817,43 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesAsync_CreateM { case 201: { - // Create the result - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(); // Get response headers string _header; + Azure.Core.Http.ETag eTag = default; + System.DateTimeOffset lastModified = default; + byte[] contentHash = default; + byte[] xMSContentCrc64 = default; + long blobSequenceNumber = default; + string encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) { - _value.ETag = new Azure.Core.Http.ETag(_header); + eTag = new Azure.Core.Http.ETag(_header); } if (response.Headers.TryGetValue("Last-Modified", out _header)) { - _value.LastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("Content-MD5", out _header)) { - _value.ContentHash = System.Convert.FromBase64String(_header); + contentHash = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - _value.XMSContentCrc64 = System.Convert.FromBase64String(_header); + xMSContentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { - _value.BlobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("x-ms-encryption-key-sha256", out _header)) { - _value.EncryptionKeySha256 = _header; + encryptionKeySha256 = _header; } + // Create the result + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(eTag, lastModified, contentHash, xMSContentCrc64, blobSequenceNumber, encryptionKeySha256); + // Create the response Azure.Response _result = new Azure.Response( @@ -8055,31 +8062,42 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage ClearPagesAsync_CreateMe { case 201: { - // Create the result - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(); // Get response headers string _header; + Azure.Core.Http.ETag eTag = default; + System.DateTimeOffset lastModified = default; + byte[] contentHash = default; + byte[] xMSContentCrc64 = default; + long blobSequenceNumber = default; + string encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) { - _value.ETag = new Azure.Core.Http.ETag(_header); + eTag = new Azure.Core.Http.ETag(_header); } if (response.Headers.TryGetValue("Last-Modified", out _header)) { - _value.LastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("Content-MD5", out _header)) { - _value.ContentHash = System.Convert.FromBase64String(_header); + contentHash = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - _value.XMSContentCrc64 = System.Convert.FromBase64String(_header); + xMSContentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { - _value.BlobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } + if (response.Headers.TryGetValue("x-ms-encryption-key-sha256", out _header)) + { + encryptionKeySha256 = _header; + } + + // Create the result + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(eTag, lastModified, contentHash, xMSContentCrc64, blobSequenceNumber, encryptionKeySha256); // Create the response Azure.Response _result = @@ -8349,36 +8367,43 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesFromUriAsync_ { case 201: { - // Create the result - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(); // Get response headers string _header; + Azure.Core.Http.ETag eTag = default; + System.DateTimeOffset lastModified = default; + byte[] contentHash = default; + byte[] xMSContentCrc64 = default; + long blobSequenceNumber = default; + string encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) { - _value.ETag = new Azure.Core.Http.ETag(_header); + eTag = new Azure.Core.Http.ETag(_header); } if (response.Headers.TryGetValue("Last-Modified", out _header)) { - _value.LastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("Content-MD5", out _header)) { - _value.ContentHash = System.Convert.FromBase64String(_header); + contentHash = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - _value.XMSContentCrc64 = System.Convert.FromBase64String(_header); + xMSContentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { - _value.BlobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("x-ms-encryption-key-sha256", out _header)) { - _value.EncryptionKeySha256 = _header; + encryptionKeySha256 = _header; } + // Create the result + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(eTag, lastModified, contentHash, xMSContentCrc64, blobSequenceNumber, encryptionKeySha256); + // Create the response Azure.Response _result = new Azure.Response( @@ -18062,53 +18087,111 @@ public static PageBlobInfo PageBlobInfo( } #endregion class PageBlobInfo -#region class PageInfo +#region struct PageInfo namespace Azure.Storage.Blobs.Models { /// /// PageInfo /// - public partial class PageInfo + public readonly partial struct PageInfo: System.IEquatable { /// /// The ETag contains a value that you can use to perform operations conditionally. If the request version is 2011-08-18 or newer, the ETag value will be in quotes. /// - public Azure.Core.Http.ETag ETag { get; internal set; } + public Azure.Core.Http.ETag ETag { get; } /// /// Returns the date and time the container was last modified. Any operation that modifies the blob, including an update of the blob's metadata or properties, changes the last-modified time of the blob. /// - public System.DateTimeOffset LastModified { get; internal set; } + public System.DateTimeOffset LastModified { get; } /// /// If the blob has an MD5 hash and this operation is to read the full blob, this response header is returned so that the client can check for message content integrity. /// #pragma warning disable CA1819 // Properties should not return arrays - public byte[] ContentHash { get; internal set; } + public byte[] ContentHash { get; } #pragma warning restore CA1819 // Properties should not return arrays /// /// This header is returned so that the client can check for message content integrity. The value of this header is computed by the Blob service; it is not necessarily the same value specified in the request headers. /// #pragma warning disable CA1819 // Properties should not return arrays - public byte[] XMSContentCrc64 { get; internal set; } + public byte[] XMSContentCrc64 { get; } #pragma warning restore CA1819 // Properties should not return arrays /// /// The current sequence number for the page blob. This is only returned for page blobs. /// - public long BlobSequenceNumber { get; internal set; } + public long BlobSequenceNumber { get; } /// /// The SHA-256 hash of the encryption key used to encrypt the pages. This header is only returned when the pages were encrypted with a customer-provided key. /// - public string EncryptionKeySha256 { get; internal set; } + public string EncryptionKeySha256 { get; } /// /// Prevent direct instantiation of PageInfo instances. /// You can use BlobsModelFactory.PageInfo instead. /// - internal PageInfo() { } + internal PageInfo( + Azure.Core.Http.ETag eTag, + System.DateTimeOffset lastModified, + byte[] contentHash, + byte[] xMSContentCrc64, + long blobSequenceNumber, + string encryptionKeySha256){ + ETag = eTag; + LastModified = lastModified; + ContentHash = contentHash; + XMSContentCrc64 = xMSContentCrc64; + BlobSequenceNumber = blobSequenceNumber; + EncryptionKeySha256 = encryptionKeySha256; + } + + /// + /// Check if two PageInfo instances are equal. + /// + /// The instance to compare to. + /// True if they're equal, false otherwise. + public bool Equals(PageInfo other) + { + if (!ETag.Equals(other.ETag)) + return false; + if (!LastModified.Equals(other.LastModified)) + return false; + if (!ContentHash.Equals(other.ContentHash)) + return false; + if (!XMSContentCrc64.Equals(other.XMSContentCrc64)) + return false; + if (!BlobSequenceNumber.Equals(other.BlobSequenceNumber)) + return false; + if (!EncryptionKeySha256.Equals(other.EncryptionKeySha256, System.StringComparison.InvariantCulture)) + return false; + + return true; + } + + /// + /// Check if two PageInfo instances are equal. + /// + /// The instance to compare to. + /// True if they're equal, false otherwise. + public override bool Equals(object obj) => obj is PageInfo && Equals((PageInfo)obj); + + /// + /// Get a hash code for the AccountInfo. + /// + public override int GetHashCode(){ + var hashCode = new Azure.Core.HashCodeBuilder(); + hashCode.Add(ETag); + hashCode.Add(LastModified); + hashCode.Add(ContentHash); + hashCode.Add(XMSContentCrc64); + hashCode.Add(BlobSequenceNumber); + hashCode.Add(EncryptionKeySha256); + + return hashCode.ToHashCode(); + } } /// @@ -18127,19 +18210,11 @@ public static PageInfo PageInfo( long blobSequenceNumber, string encryptionKeySha256) { - return new PageInfo() - { - ETag = eTag, - LastModified = lastModified, - ContentHash = contentHash, - XMSContentCrc64 = xMSContentCrc64, - BlobSequenceNumber = blobSequenceNumber, - EncryptionKeySha256 = encryptionKeySha256, - }; + return new PageInfo(eTag, lastModified, contentHash, xMSContentCrc64, blobSequenceNumber, encryptionKeySha256); } } } -#endregion class PageInfo +#endregion struct PageInfo #region class PageList namespace Azure.Storage.Blobs.Models diff --git a/sdk/storage/Azure.Storage.Blobs/swagger/readme.md b/sdk/storage/Azure.Storage.Blobs/swagger/readme.md index d3f9404b35a5d..cd8c9ea33a5f1 100644 --- a/sdk/storage/Azure.Storage.Blobs/swagger/readme.md +++ b/sdk/storage/Azure.Storage.Blobs/swagger/readme.md @@ -684,6 +684,7 @@ directive: transform: > $.put.responses["201"]["x-az-response-name"] = "PageInfo"; $.put.responses["201"].description = "The operation completed successfully."; + $.put.responses["201"]["x-az-struct"] = true; $.put.responses["201"].headers["x-ms-blob-sequence-number"].description = "The current sequence number for the page blob. This is only returned for page blobs."; $.put.responses["201"].headers["x-ms-request-server-encrypted"]["x-az-demote-header"] = true; ``` @@ -696,6 +697,7 @@ directive: transform: > $.put.responses["201"]["x-az-response-name"] = "PageInfo"; $.put.responses["201"].description = "The operation completed successfully."; + $.put.responses["201"]["x-az-struct"] = true; $.put.responses["201"].headers["x-ms-blob-sequence-number"].description = "The current sequence number for the page blob. This is only returned for page blobs."; $.put.responses["201"].headers["x-ms-request-server-encrypted"] = { "x-ms-client-name": "IsServerEncrypted", @@ -703,6 +705,11 @@ directive: "x-az-demote-header": true, "description": "The value of this header is set to true if the contents of the request are successfully encrypted using the specified algorithm, and false otherwise." }; + $.put.responses["201"].headers["x-ms-encryption-key-sha256"] = { + "x-ms-client-name": "EncryptionKeySha256", + "type": "string", + "description": "The SHA-256 hash of the encryption key used to encrypt the blob. This header is only returned when the blob was encrypted with a customer-provided key." + }; ``` ### /{containerName}/{blob}?comp=page&update&fromUrl @@ -714,6 +721,7 @@ directive: $.put.operationId = "PageBlob_UploadPagesFromUri"; $.put.responses["201"]["x-az-response-name"] = "PageInfo"; $.put.responses["201"].description = "The operation completed successfully."; + $.put.responses["201"]["x-az-struct"] = true; $.put.responses["201"].headers["x-ms-blob-sequence-number"].description = "The current sequence number for the page blob. This is only returned for page blobs."; $.put.responses["201"].headers["x-ms-request-server-encrypted"]["x-az-demote-header"] = true; $.put.responses["304"] = { diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index 59c45ca744ea3..7bc3955c6ee14 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -967,7 +967,11 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`public bool Equals(${naming.type(type.name)} other)`); w.scope('{', '}', () => { for (const property of properties) { - w.line(`if (!${naming.property(property.clientName)}.Equals(other.${naming.property(property.clientName)}))`); + if (types.getDeclarationType(property.model, property.required, property.readonly) === "string") { + w.line(`if (!${naming.property(property.clientName)}.Equals(other.${naming.property(property.clientName)}, System.StringComparison.InvariantCulture))`); + } else { + w.line(`if (!${naming.property(property.clientName)}.Equals(other.${naming.property(property.clientName)}))`); + } w.line(` return false;`); } w.line(); From eb4727657b7307aaf0f3a4570fbba0c8de44002b Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Mon, 30 Sep 2019 01:11:58 -0700 Subject: [PATCH 05/14] Change PageRange class to struct --- .../src/Generated/BlobRestClient.cs | 64 ++++++++++++++----- .../Azure.Storage.Blobs/swagger/readme.md | 9 +++ .../swagger/Generator/readme.md | 1 + .../swagger/Generator/src/generator.ts | 17 ++++- 4 files changed, 73 insertions(+), 18 deletions(-) diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index fc70fea542a2e..7f5095b1f3cb8 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -18179,7 +18179,7 @@ public bool Equals(PageInfo other) public override bool Equals(object obj) => obj is PageInfo && Equals((PageInfo)obj); /// - /// Get a hash code for the AccountInfo. + /// Get a hash code for the PageInfo. /// public override int GetHashCode(){ var hashCode = new Azure.Core.HashCodeBuilder(); @@ -18301,29 +18301,67 @@ public static PageList PageList( } #endregion class PageList -#region class PageRange +#region struct PageRange namespace Azure.Storage.Blobs.Models { /// /// PageRange /// - public partial class PageRange + public readonly partial struct PageRange: System.IEquatable { /// /// Start /// - public long Start { get; internal set; } + public long Start { get; } /// /// End /// - public long End { get; internal set; } + public long End { get; } /// /// Prevent direct instantiation of PageRange instances. /// You can use BlobsModelFactory.PageRange instead. /// - internal PageRange() { } + internal PageRange( + long start, + long end){ + Start = start; + End = end; + } + + /// + /// Check if two PageRange instances are equal. + /// + /// The instance to compare to. + /// True if they're equal, false otherwise. + public bool Equals(PageRange other) + { + if (!Start.Equals(other.Start)) + return false; + if (!End.Equals(other.End)) + return false; + + return true; + } + + /// + /// Check if two PageRange instances are equal. + /// + /// The instance to compare to. + /// True if they're equal, false otherwise. + public override bool Equals(object obj) => obj is PageRange && Equals((PageRange)obj); + + /// + /// Get a hash code for the PageRange. + /// + public override int GetHashCode(){ + var hashCode = new Azure.Core.HashCodeBuilder(); + hashCode.Add(Start); + hashCode.Add(End); + + return hashCode.ToHashCode(); + } /// /// Deserializes XML into a new PageRange instance. @@ -18333,9 +18371,9 @@ internal PageRange() { } internal static Azure.Storage.Blobs.Models.PageRange FromXml(System.Xml.Linq.XElement element) { System.Diagnostics.Debug.Assert(element != null); - Azure.Storage.Blobs.Models.PageRange _value = new Azure.Storage.Blobs.Models.PageRange(); - _value.Start = long.Parse(element.Element(System.Xml.Linq.XName.Get("Start", "")).Value, System.Globalization.CultureInfo.InvariantCulture); - _value.End = long.Parse(element.Element(System.Xml.Linq.XName.Get("End", "")).Value, System.Globalization.CultureInfo.InvariantCulture); + long start = long.Parse(element.Element(System.Xml.Linq.XName.Get("Start", "")).Value, System.Globalization.CultureInfo.InvariantCulture); + long end = long.Parse(element.Element(System.Xml.Linq.XName.Get("End", "")).Value, System.Globalization.CultureInfo.InvariantCulture); + Azure.Storage.Blobs.Models.PageRange _value = new Azure.Storage.Blobs.Models.PageRange(start, end); CustomizeFromXml(element, _value); return _value; } @@ -18355,15 +18393,11 @@ public static PageRange PageRange( long start, long end) { - return new PageRange() - { - Start = start, - End = end, - }; + return new PageRange(start, end); } } } -#endregion class PageRange +#endregion struct PageRange #region class PageRangesInfo namespace Azure.Storage.Blobs.Models diff --git a/sdk/storage/Azure.Storage.Blobs/swagger/readme.md b/sdk/storage/Azure.Storage.Blobs/swagger/readme.md index cd8c9ea33a5f1..8651885e5d132 100644 --- a/sdk/storage/Azure.Storage.Blobs/swagger/readme.md +++ b/sdk/storage/Azure.Storage.Blobs/swagger/readme.md @@ -765,6 +765,15 @@ directive: }; ``` +### Define PageRange as struct +``` yaml +directive: +- from: swagger-document + where: $.definitions.PageRange + transform: > + $["x-az-struct"] = true; +``` + ### /{containerName}/{blob}?comp=properties&Resize ``` yaml directive: diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/readme.md b/sdk/storage/Azure.Storage.Common/swagger/Generator/readme.md index a0115a6a0d05f..22eab5bf11a2a 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/readme.md +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/readme.md @@ -13,6 +13,7 @@ We support a number of extensions including using the vendor prefix `x-az-`: - `x-az-skip-path-components`: Whether to skip any path components and always assume a fully formed URL to the resource (this currently must be set to `true`). - `x-az-include-sync-methods`: Whether to generate support for sync methods. The default value is `false` (this flag should go away soon and always be `true`). - `x-az-stream`: Whether to generate a non buffered request that takes owhership of the response stream. The default value is `false`. +- `x-az-struct`: Indicates whether a model is struct or not. The default value is `false`. ### Autorest plugin configuration The AutoRest example at https://github.com/Azure/autorest-extension-helloworld diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index 7bc3955c6ee14..34f8e84579892 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -986,7 +986,7 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`public override bool Equals(object obj) => obj is ${naming.type(type.name)} && Equals((${naming.type(type.name)})obj);`); w.line(); w.line(`/// `) - w.line(`/// Get a hash code for the AccountInfo.`); + w.line(`/// Get a hash code for the ${naming.type(type.name)}.`); w.line(`/// `); w.write(`public override int GetHashCode()`); w.scope('{', '}', () => { @@ -1194,7 +1194,7 @@ function generateDeserialize(w: IndentWriter, service: IService, type: IObjectTy // Create the model const valueName = '_value'; const skipInit = (Object.values(type.properties)).some(p => isObjectType(p.model) || (isPrimitiveType(p.model) && (!!p.model.itemType || p.model.type === `dictionary`))); - w.line(`${types.getName(type)} ${valueName} = new ${types.getName(type)}(${skipInit ? 'true' : ''});`); + if (!type.struct) { w.line(`${types.getName(type)} ${valueName} = new ${types.getName(type)}(${skipInit ? 'true' : ''});`); } // Deserialize each of its properties for (const property of properties) { @@ -1284,7 +1284,8 @@ function generateDeserialize(w: IndentWriter, service: IService, type: IObjectTy } } else { // Assign the value - const assignment = `${valueName}.${naming.property(property.clientName)} = ${parse(target, property.model)};`; + const assignment = type.struct ? `${types.getDeclarationType(property.model, true, false, true)} ${naming.parameter(property.clientName)} = ${parse(target, property.model)};` + : `${valueName}.${naming.property(property.clientName)} = ${parse(target, property.model)};`; if (property.required) { // If a property is required, the XML element will always be there so we can just use it w.line(assignment); @@ -1300,6 +1301,16 @@ function generateDeserialize(w: IndentWriter, service: IService, type: IObjectTy } } } + if (type.struct) { + const Separator = IndentWriter.createFenceposter(); + w.write(`${types.getName(type)} ${valueName} = new ${types.getName(type)}(`); + for (const property of properties) { + if (Separator()) { w.write(`, `); } + w.write(`${naming.parameter(property.clientName)}`); + } + w.write(`);`); + w.line(); + } w.line(`Customize${fromName}(${rootName}, ${valueName});`); w.line(`return ${valueName};`); }); From 59447e227bc42b5a17356a2aeb5244ff0385e826 Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Mon, 30 Sep 2019 01:41:57 -0700 Subject: [PATCH 06/14] Remove unnecessary checks --- .../Azure.Storage.Common/swagger/Generator/src/generator.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index 34f8e84579892..2b04efed83fcb 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -944,12 +944,9 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.write(`internal ${naming.type(type.name)}(`); w.scope(() => { const separator = IndentWriter.createFenceposter(); - // Sort `= default` parameters last - properties.sort((a: IProperty, b: IProperty) => a.required ? -1 : b.required ? 1 : 0); for (const property of properties) { if (separator()) { w.line(`,`); } w.write(`${types.getDeclarationType(property.model, property.required, property.readonly)} ${naming.parameter(property.clientName)}`); - if (!property.required) { w.write(` = default`); } } w.write(`)`); w.scope('{', '}', () => { From 24512d3bf691496036fecb017a9e6b7403ea7466 Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Mon, 30 Sep 2019 14:52:16 -0700 Subject: [PATCH 07/14] Address comments --- .../src/Generated/BlobRestClient.cs | 132 +++++++------ .../Azure.Storage.Blobs/tests/PageInfoTest.cs | 178 ++++++++++++++++++ .../swagger/Generator/src/generator.ts | 26 ++- sdk/storage/generate.ps1 | 4 +- 4 files changed, 275 insertions(+), 65 deletions(-) create mode 100644 sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index 66d9ed37faabd..80a320dcd3a7e 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -838,19 +838,18 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage GetAccountInfoAsync_Crea // Get response headers string _header; - Azure.Storage.Blobs.Models.SkuName skuName = default; - Azure.Storage.Blobs.Models.AccountKind accountKind = default; + Azure.Storage.Blobs.Models.SkuName _skuName = default; + Azure.Storage.Blobs.Models.AccountKind _accountKind = default; if (response.Headers.TryGetValue("x-ms-sku-name", out _header)) { - skuName = Azure.Storage.Blobs.BlobRestClient.Serialization.ParseSkuName(_header); + _skuName = Azure.Storage.Blobs.BlobRestClient.Serialization.ParseSkuName(_header); } if (response.Headers.TryGetValue("x-ms-account-kind", out _header)) { - accountKind = (Azure.Storage.Blobs.Models.AccountKind)System.Enum.Parse(typeof(Azure.Storage.Blobs.Models.AccountKind), _header, false); + _accountKind = (Azure.Storage.Blobs.Models.AccountKind)System.Enum.Parse(typeof(Azure.Storage.Blobs.Models.AccountKind), _header, false); } - // Create the result - Azure.Storage.Blobs.Models.AccountInfo _value = new Azure.Storage.Blobs.Models.AccountInfo(skuName, accountKind); + Azure.Storage.Blobs.Models.AccountInfo _value = new Azure.Storage.Blobs.Models.AccountInfo(_skuName, _accountKind); // Create the response Azure.Response _result = @@ -7820,39 +7819,38 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesAsync_CreateM // Get response headers string _header; - Azure.Core.Http.ETag eTag = default; - System.DateTimeOffset lastModified = default; - byte[] contentHash = default; - byte[] xMSContentCrc64 = default; - long blobSequenceNumber = default; - string encryptionKeySha256 = default; + Azure.Core.Http.ETag _eTag = default; + System.DateTimeOffset _lastModified = default; + byte[] _contentHash = default; + byte[] _xMSContentCrc64 = default; + long _blobSequenceNumber = default; + string _encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) { - eTag = new Azure.Core.Http.ETag(_header); + _eTag = new Azure.Core.Http.ETag(_header); } if (response.Headers.TryGetValue("Last-Modified", out _header)) { - lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + _lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("Content-MD5", out _header)) { - contentHash = System.Convert.FromBase64String(_header); + _contentHash = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - xMSContentCrc64 = System.Convert.FromBase64String(_header); + _xMSContentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { - blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + _blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("x-ms-encryption-key-sha256", out _header)) { - encryptionKeySha256 = _header; + _encryptionKeySha256 = _header; } - // Create the result - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(eTag, lastModified, contentHash, xMSContentCrc64, blobSequenceNumber, encryptionKeySha256); + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _xMSContentCrc64, _blobSequenceNumber, _encryptionKeySha256); // Create the response Azure.Response _result = @@ -8065,39 +8063,38 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage ClearPagesAsync_CreateMe // Get response headers string _header; - Azure.Core.Http.ETag eTag = default; - System.DateTimeOffset lastModified = default; - byte[] contentHash = default; - byte[] xMSContentCrc64 = default; - long blobSequenceNumber = default; - string encryptionKeySha256 = default; + Azure.Core.Http.ETag _eTag = default; + System.DateTimeOffset _lastModified = default; + byte[] _contentHash = default; + byte[] _xMSContentCrc64 = default; + long _blobSequenceNumber = default; + string _encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) { - eTag = new Azure.Core.Http.ETag(_header); + _eTag = new Azure.Core.Http.ETag(_header); } if (response.Headers.TryGetValue("Last-Modified", out _header)) { - lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + _lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("Content-MD5", out _header)) { - contentHash = System.Convert.FromBase64String(_header); + _contentHash = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - xMSContentCrc64 = System.Convert.FromBase64String(_header); + _xMSContentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { - blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + _blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("x-ms-encryption-key-sha256", out _header)) { - encryptionKeySha256 = _header; + _encryptionKeySha256 = _header; } - // Create the result - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(eTag, lastModified, contentHash, xMSContentCrc64, blobSequenceNumber, encryptionKeySha256); + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _xMSContentCrc64, _blobSequenceNumber, _encryptionKeySha256); // Create the response Azure.Response _result = @@ -8370,39 +8367,38 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesFromUriAsync_ // Get response headers string _header; - Azure.Core.Http.ETag eTag = default; - System.DateTimeOffset lastModified = default; - byte[] contentHash = default; - byte[] xMSContentCrc64 = default; - long blobSequenceNumber = default; - string encryptionKeySha256 = default; + Azure.Core.Http.ETag _eTag = default; + System.DateTimeOffset _lastModified = default; + byte[] _contentHash = default; + byte[] _xMSContentCrc64 = default; + long _blobSequenceNumber = default; + string _encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) { - eTag = new Azure.Core.Http.ETag(_header); + _eTag = new Azure.Core.Http.ETag(_header); } if (response.Headers.TryGetValue("Last-Modified", out _header)) { - lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + _lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("Content-MD5", out _header)) { - contentHash = System.Convert.FromBase64String(_header); + _contentHash = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - xMSContentCrc64 = System.Convert.FromBase64String(_header); + _xMSContentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { - blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + _blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("x-ms-encryption-key-sha256", out _header)) { - encryptionKeySha256 = _header; + _encryptionKeySha256 = _header; } - // Create the result - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(eTag, lastModified, contentHash, xMSContentCrc64, blobSequenceNumber, encryptionKeySha256); + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _xMSContentCrc64, _blobSequenceNumber, _encryptionKeySha256); // Create the response Azure.Response _result = @@ -12847,9 +12843,13 @@ internal AccountInfo( public bool Equals(AccountInfo other) { if (!SkuName.Equals(other.SkuName)) + { return false; + } if (!AccountKind.Equals(other.AccountKind)) + { return false; + } return true; } @@ -12864,7 +12864,8 @@ public bool Equals(AccountInfo other) /// /// Get a hash code for the AccountInfo. /// - public override int GetHashCode(){ + public override int GetHashCode() + { var hashCode = new Azure.Core.HashCodeBuilder(); hashCode.Add(SkuName); hashCode.Add(AccountKind); @@ -17974,17 +17975,29 @@ internal PageInfo( public bool Equals(PageInfo other) { if (!ETag.Equals(other.ETag)) + { return false; + } if (!LastModified.Equals(other.LastModified)) + { return false; - if (!ContentHash.Equals(other.ContentHash)) + } + if (!Equals(ContentHash, other.ContentHash)) + { return false; - if (!XMSContentCrc64.Equals(other.XMSContentCrc64)) + } + if (!Equals(XMSContentCrc64, other.XMSContentCrc64)) + { return false; + } if (!BlobSequenceNumber.Equals(other.BlobSequenceNumber)) + { return false; - if (!EncryptionKeySha256.Equals(other.EncryptionKeySha256, System.StringComparison.InvariantCulture)) + } + if (!System.StringComparer.Ordinal.Equals(EncryptionKeySha256, other.EncryptionKeySha256)) + { return false; + } return true; } @@ -17999,14 +18012,18 @@ public bool Equals(PageInfo other) /// /// Get a hash code for the PageInfo. /// - public override int GetHashCode(){ + public override int GetHashCode() + { var hashCode = new Azure.Core.HashCodeBuilder(); hashCode.Add(ETag); hashCode.Add(LastModified); hashCode.Add(ContentHash); hashCode.Add(XMSContentCrc64); hashCode.Add(BlobSequenceNumber); - hashCode.Add(EncryptionKeySha256); + if (EncryptionKeySha256 != null) + { + hashCode.Add(EncryptionKeySha256, System.StringComparer.Ordinal); + } return hashCode.ToHashCode(); } @@ -18156,9 +18173,13 @@ internal PageRange( public bool Equals(PageRange other) { if (!Start.Equals(other.Start)) + { return false; + } if (!End.Equals(other.End)) + { return false; + } return true; } @@ -18173,7 +18194,8 @@ public bool Equals(PageRange other) /// /// Get a hash code for the PageRange. /// - public override int GetHashCode(){ + public override int GetHashCode() + { var hashCode = new Azure.Core.HashCodeBuilder(); hashCode.Add(Start); hashCode.Add(End); diff --git a/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs b/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs new file mode 100644 index 0000000000000..0d15d93666422 --- /dev/null +++ b/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs @@ -0,0 +1,178 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Azure.Storage.Blobs.Models; +using NUnit.Framework; + +namespace Azure.Storage.Blobs.Tests +{ + public class PageInfoTest + { + [Test] + public void EqualsReturnsTrueForEqualValues() + { + var hash = new byte[] { 1, 2, 3 }; + + var info1 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + hash, + hash, + 1, + "key1"); + + var info2 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + hash, + hash, + 1, + "key1"); + + Assert.True(info1.Equals(info2)); + Assert.True(info2.Equals(info1)); + + Assert.AreEqual(info1.GetHashCode(), info2.GetHashCode()); + } + + [Test] + public void EqualsReturnsTrueForNullValues() + { + var info1 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + null, + null, + 1, + null); + + var info2 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + null, + null, + 1, + null); + + Assert.True(info1.Equals(info2)); + Assert.True(info2.Equals(info1)); + + Assert.AreEqual(info1.GetHashCode(), info2.GetHashCode()); + + } + + [Test] + public void EqualsReturnsFalseIfCompareContentHashWithNull() + { + var hash = new byte[] { 1, 2, 3 }; + + var info1 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + null, + hash, + 1, + "key1"); + + var info2 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + hash, + hash, + 1, + "key1"); + + Assert.True(!info1.Equals(info2)); + Assert.True(!info2.Equals(info1)); + + Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); + + } + + [Test] + public void EqualsReturnsFalseIfCompareXMSContentCrc64WithNull() + { + var hash = new byte[] { 1, 2, 3 }; + + var info1 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + hash, + null, + 1, + "key1"); + + var info2 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + hash, + hash, + 1, + "key1"); + + Assert.True(!info1.Equals(info2)); + Assert.True(!info2.Equals(info1)); + + Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); + + } + + + [Test] + public void EqualsReturnFalseIfCompareDifferentValues() + { + var hash = new byte[] { 1, 2, 3 }; + + var info1 = new PageInfo( + new Core.Http.ETag("B"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + hash, + hash, + 1, + "key1"); + + var info2 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 11, 25, 1, 1, 1, TimeSpan.Zero), + hash, + hash, + 2, + "key2"); + + Assert.True(!info1.Equals(info2)); + Assert.True(!info2.Equals(info1)); + + Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); + } + + [Test] + public void EqualsReturnsFalseIfCompareByteArrayByValues() + { + var hash1 = new byte[] { 1, 2, 3 }; + var hash2 = new byte[] { 1, 2, 3 }; + + var info1 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + hash1, + hash1, + 1, + "key1"); + + var info2 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + hash2, + hash1, + 1, + "key1"); + + Assert.True(!info1.Equals(info2)); + Assert.True(!info2.Equals(info1)); + + Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); + + } + } +} diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index 2b04efed83fcb..a2a001a110e37 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -592,7 +592,7 @@ function generateOperation(w: IndentWriter, serviceModel: IServiceModel, group: w.line(`string ${headerName};`); if (response.struct) { for (const header of headers) { - w.line(`${types.getDeclarationType(header.model, true, false, true)} ${naming.parameter(header.clientName)} = default;`); + w.line(`${types.getDeclarationType(header.model, true, false, true)} _${naming.parameter(header.clientName)} = default;`); } } for (const header of headers) { @@ -610,7 +610,7 @@ function generateOperation(w: IndentWriter, serviceModel: IServiceModel, group: w.line(`if (${responseName}.Headers.TryGetValue("${header.name}", out ${headerName}))`); w.scope('{', '}', () => { if (response.struct) { - w.write(`${naming.parameter(header.clientName)} = `); + w.write(`_${naming.parameter(header.clientName)} = `); } else { w.write(`${valueName}.${naming.pascalCase(header.clientName)} = `); } @@ -628,12 +628,11 @@ function generateOperation(w: IndentWriter, serviceModel: IServiceModel, group: } if (response.struct) { w.line(); - w.line(`// Create the result`); const Separator = IndentWriter.createFenceposter(); w.write(`${types.getName(model)} ${valueName} = new ${types.getName(model)}(`); for (const header of headers) { if (Separator()) { w.write(`, `); } - w.write(`${naming.parameter(header.clientName)}`); + w.write(`_${naming.parameter(header.clientName)}`); } w.write(`);`); w.line(); @@ -965,11 +964,15 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.scope('{', '}', () => { for (const property of properties) { if (types.getDeclarationType(property.model, property.required, property.readonly) === "string") { - w.line(`if (!${naming.property(property.clientName)}.Equals(other.${naming.property(property.clientName)}, System.StringComparison.InvariantCulture))`); + w.line(`if (!System.StringComparer.Ordinal.Equals(${naming.property(property.clientName)}, other.${naming.property(property.clientName)}))`); + } else if (types.getDeclarationType(property.model, property.required, property.readonly).includes("[]")) { + w.line(`if (!Equals(${naming.property(property.clientName)}, other.${naming.property(property.clientName)}))`); } else { w.line(`if (!${naming.property(property.clientName)}.Equals(other.${naming.property(property.clientName)}))`); } - w.line(` return false;`); + w.scope('{', '}', () => { + w.line(`return false;`); + }); } w.line(); w.line(`return true;`); @@ -985,11 +988,18 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`/// `) w.line(`/// Get a hash code for the ${naming.type(type.name)}.`); w.line(`/// `); - w.write(`public override int GetHashCode()`); + w.line(`public override int GetHashCode()`); w.scope('{', '}', () => { w.line(`var hashCode = new Azure.Core.HashCodeBuilder();`); for (const property of properties) { - w.line(`hashCode.Add(${naming.property(property.clientName)});`); + if (types.getDeclarationType(property.model, property.required, property.readonly) === "string") { + w.line(`if (EncryptionKeySha256 != null)`) + w.scope('{', '}', () => { + w.line(`hashCode.Add(${naming.property(property.clientName)}, System.StringComparer.Ordinal);`); + }); + } else { + w.line(`hashCode.Add(${naming.property(property.clientName)});`); + } } w.line(); w.line(`return hashCode.ToHashCode();`); diff --git a/sdk/storage/generate.ps1 b/sdk/storage/generate.ps1 index dc0946e92872b..3c3ad3e897feb 100644 --- a/sdk/storage/generate.ps1 +++ b/sdk/storage/generate.ps1 @@ -10,7 +10,7 @@ autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose cd $PSScriptRoot/Azure.Storage.Queues/swagger/ autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose -# cd $PSScriptRoot/Azure.Storage.Files.DataLake/swagger/ -# autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose + cd $PSScriptRoot/Azure.Storage.Files.DataLake/swagger/ + autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose popd From 5c3e1250c63208a53d20a6cd0aa9da3715547a51 Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Mon, 30 Sep 2019 14:53:54 -0700 Subject: [PATCH 08/14] Remove extra space --- sdk/storage/generate.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/storage/generate.ps1 b/sdk/storage/generate.ps1 index 3c3ad3e897feb..8a8241c744588 100644 --- a/sdk/storage/generate.ps1 +++ b/sdk/storage/generate.ps1 @@ -10,7 +10,7 @@ autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose cd $PSScriptRoot/Azure.Storage.Queues/swagger/ autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose - cd $PSScriptRoot/Azure.Storage.Files.DataLake/swagger/ - autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose +cd $PSScriptRoot/Azure.Storage.Files.DataLake/swagger/ +autorest --use=$PSScriptRoot/Azure.Storage.Common/swagger/Generator/ --verbose popd From a99fe024bbef0e5771013a358920063821f8bc6b Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Mon, 30 Sep 2019 15:04:16 -0700 Subject: [PATCH 09/14] "{" on a new line. --- .../Azure.Storage.Blobs/src/Generated/BlobRestClient.cs | 9 ++++++--- .../swagger/Generator/src/generator.ts | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index 80a320dcd3a7e..06831e8b1809b 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -12830,7 +12830,8 @@ namespace Azure.Storage.Blobs.Models /// internal AccountInfo( Azure.Storage.Blobs.Models.SkuName skuName, - Azure.Storage.Blobs.Models.AccountKind accountKind){ + Azure.Storage.Blobs.Models.AccountKind accountKind) + { SkuName = skuName; AccountKind = accountKind; } @@ -17958,7 +17959,8 @@ internal PageInfo( byte[] contentHash, byte[] xMSContentCrc64, long blobSequenceNumber, - string encryptionKeySha256){ + string encryptionKeySha256) + { ETag = eTag; LastModified = lastModified; ContentHash = contentHash; @@ -18160,7 +18162,8 @@ namespace Azure.Storage.Blobs.Models /// internal PageRange( long start, - long end){ + long end) + { Start = start; End = end; } diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index a2a001a110e37..428fb3e3b1f28 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -947,7 +947,7 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType if (separator()) { w.line(`,`); } w.write(`${types.getDeclarationType(property.model, property.required, property.readonly)} ${naming.parameter(property.clientName)}`); } - w.write(`)`); + w.line(`)`); w.scope('{', '}', () => { for (const property of properties) { w.line(`${naming.property(property.clientName)} = ${naming.parameter(property.clientName)};`); From 770986e8b1332a5a3dc7d819b0dee3097a95fa6f Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Mon, 30 Sep 2019 16:02:33 -0700 Subject: [PATCH 10/14] Generate code after merging into master --- .../src/Generated/BlobRestClient.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index 054a80378f480..1f00f709cc126 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -7822,7 +7822,7 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesAsync_CreateM Azure.Core.Http.ETag _eTag = default; System.DateTimeOffset _lastModified = default; byte[] _contentHash = default; - byte[] _xMSContentCrc64 = default; + byte[] _contentCrc64 = default; long _blobSequenceNumber = default; string _encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) @@ -7839,7 +7839,7 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesAsync_CreateM } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - _xMSContentCrc64 = System.Convert.FromBase64String(_header); + _contentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { @@ -7850,7 +7850,7 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesAsync_CreateM _encryptionKeySha256 = _header; } - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _xMSContentCrc64, _blobSequenceNumber, _encryptionKeySha256); + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _contentCrc64, _blobSequenceNumber, _encryptionKeySha256); // Create the response Azure.Response _result = @@ -8066,7 +8066,7 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage ClearPagesAsync_CreateMe Azure.Core.Http.ETag _eTag = default; System.DateTimeOffset _lastModified = default; byte[] _contentHash = default; - byte[] _xMSContentCrc64 = default; + byte[] _contentCrc64 = default; long _blobSequenceNumber = default; string _encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) @@ -8083,7 +8083,7 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage ClearPagesAsync_CreateMe } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - _xMSContentCrc64 = System.Convert.FromBase64String(_header); + _contentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { @@ -8094,7 +8094,7 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage ClearPagesAsync_CreateMe _encryptionKeySha256 = _header; } - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _xMSContentCrc64, _blobSequenceNumber, _encryptionKeySha256); + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _contentCrc64, _blobSequenceNumber, _encryptionKeySha256); // Create the response Azure.Response _result = @@ -8370,7 +8370,7 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesFromUriAsync_ Azure.Core.Http.ETag _eTag = default; System.DateTimeOffset _lastModified = default; byte[] _contentHash = default; - byte[] _xMSContentCrc64 = default; + byte[] _contentCrc64 = default; long _blobSequenceNumber = default; string _encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) @@ -8387,7 +8387,7 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesFromUriAsync_ } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - _xMSContentCrc64 = System.Convert.FromBase64String(_header); + _contentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { @@ -8398,7 +8398,7 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesFromUriAsync_ _encryptionKeySha256 = _header; } - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _xMSContentCrc64, _blobSequenceNumber, _encryptionKeySha256); + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _contentCrc64, _blobSequenceNumber, _encryptionKeySha256); // Create the response Azure.Response _result = @@ -17936,7 +17936,7 @@ namespace Azure.Storage.Blobs.Models /// This header is returned so that the client can check for message content integrity. The value of this header is computed by the Blob service; it is not necessarily the same value specified in the request headers. /// #pragma warning disable CA1819 // Properties should not return arrays - public byte[] XMSContentCrc64 { get; } + public byte[] ContentCrc64 { get; } #pragma warning restore CA1819 // Properties should not return arrays /// @@ -17957,14 +17957,14 @@ internal PageInfo( Azure.Core.Http.ETag eTag, System.DateTimeOffset lastModified, byte[] contentHash, - byte[] xMSContentCrc64, + byte[] contentCrc64, long blobSequenceNumber, string encryptionKeySha256) { ETag = eTag; LastModified = lastModified; ContentHash = contentHash; - XMSContentCrc64 = xMSContentCrc64; + ContentCrc64 = contentCrc64; BlobSequenceNumber = blobSequenceNumber; EncryptionKeySha256 = encryptionKeySha256; } @@ -17988,7 +17988,7 @@ public bool Equals(PageInfo other) { return false; } - if (!Equals(XMSContentCrc64, other.XMSContentCrc64)) + if (!Equals(ContentCrc64, other.ContentCrc64)) { return false; } @@ -18020,7 +18020,7 @@ public override int GetHashCode() hashCode.Add(ETag); hashCode.Add(LastModified); hashCode.Add(ContentHash); - hashCode.Add(XMSContentCrc64); + hashCode.Add(ContentCrc64); hashCode.Add(BlobSequenceNumber); if (EncryptionKeySha256 != null) { @@ -18047,7 +18047,7 @@ public static PageInfo PageInfo( long blobSequenceNumber, string encryptionKeySha256) { - return new PageInfo(eTag, lastModified, contentHash, xMSContentCrc64, blobSequenceNumber, encryptionKeySha256); + return new PageInfo(eTag, lastModified, contentHash, contentCrc64, blobSequenceNumber, encryptionKeySha256); } } } From 5a6750439f6e023845c45725d36caf4450d56597 Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Mon, 30 Sep 2019 17:18:17 -0700 Subject: [PATCH 11/14] Compare byte arrays by value and update related tests --- .../src/Generated/BlobRestClient.cs | 4 +- .../Azure.Storage.Blobs/tests/PageInfoTest.cs | 85 ++++++++++++------- .../swagger/Generator/src/generator.ts | 8 +- 3 files changed, 63 insertions(+), 34 deletions(-) diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index 1f00f709cc126..ba763c960168c 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -17984,11 +17984,11 @@ public bool Equals(PageInfo other) { return false; } - if (!Equals(ContentHash, other.ContentHash)) + if (!Equals(ContentHash, other.ContentHash) && (ContentHash == null || other.ContentHash == null || !System.Linq.Enumerable.SequenceEqual(ContentHash, other.ContentHash))) { return false; } - if (!Equals(ContentCrc64, other.ContentCrc64)) + if (!Equals(ContentCrc64, other.ContentCrc64) && (ContentCrc64 == null || other.ContentCrc64 == null || !System.Linq.Enumerable.SequenceEqual(ContentCrc64, other.ContentCrc64))) { return false; } diff --git a/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs b/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs index 0d15d93666422..4d2c678ab92e7 100644 --- a/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs +++ b/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs @@ -63,43 +63,71 @@ public void EqualsReturnsTrueForNullValues() } [Test] - public void EqualsReturnsFalseIfCompareContentHashWithNull() + public void EqualsReturnsTrueIfCompareContentHashByValues() { - var hash = new byte[] { 1, 2, 3 }; + var hash1 = new byte[] { 1, 2, 3 }; + var hash2 = new byte[] { 1, 2, 3 }; var info1 = new PageInfo( new Core.Http.ETag("A"), new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), - null, - hash, + hash1, + hash1, 1, "key1"); var info2 = new PageInfo( new Core.Http.ETag("A"), new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), - hash, - hash, + hash2, + hash1, 1, "key1"); - Assert.True(!info1.Equals(info2)); - Assert.True(!info2.Equals(info1)); + Assert.True(info1.Equals(info2)); + Assert.True(info2.Equals(info1)); Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); + } + + [Test] + public void EqualsReturnsTrueIfCompareContentCrc64ByValues() + { + var hash1 = new byte[] { 1, 2, 3 }; + var hash2 = new byte[] { 1, 2, 3 }; + + var info1 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + hash1, + hash1, + 1, + "key1"); + + var info2 = new PageInfo( + new Core.Http.ETag("A"), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), + hash1, + hash2, + 1, + "key1"); + + Assert.True(info1.Equals(info2)); + Assert.True(info2.Equals(info1)); + Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); } [Test] - public void EqualsReturnsFalseIfCompareXMSContentCrc64WithNull() + public void EqualsReturnsFalseIfCompareContentHashWithNull() { var hash = new byte[] { 1, 2, 3 }; var info1 = new PageInfo( new Core.Http.ETag("A"), new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), - hash, null, + hash, 1, "key1"); @@ -118,61 +146,60 @@ public void EqualsReturnsFalseIfCompareXMSContentCrc64WithNull() } - [Test] - public void EqualsReturnFalseIfCompareDifferentValues() + public void EqualsReturnsFalseIfCompareContentCrc64WithNull() { var hash = new byte[] { 1, 2, 3 }; var info1 = new PageInfo( - new Core.Http.ETag("B"), + new Core.Http.ETag("A"), new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), hash, - hash, + null, 1, "key1"); var info2 = new PageInfo( new Core.Http.ETag("A"), - new DateTimeOffset(2019, 11, 25, 1, 1, 1, TimeSpan.Zero), + new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), hash, hash, - 2, - "key2"); + 1, + "key1"); Assert.True(!info1.Equals(info2)); Assert.True(!info2.Equals(info1)); Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); + } + [Test] - public void EqualsReturnsFalseIfCompareByteArrayByValues() + public void EqualsReturnFalseIfCompareDifferentValues() { - var hash1 = new byte[] { 1, 2, 3 }; - var hash2 = new byte[] { 1, 2, 3 }; + var hash = new byte[] { 1, 2, 3 }; var info1 = new PageInfo( - new Core.Http.ETag("A"), + new Core.Http.ETag("B"), new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), - hash1, - hash1, + hash, + hash, 1, "key1"); var info2 = new PageInfo( new Core.Http.ETag("A"), - new DateTimeOffset(2019, 9, 25, 1, 1, 1, TimeSpan.Zero), - hash2, - hash1, - 1, - "key1"); + new DateTimeOffset(2019, 11, 25, 1, 1, 1, TimeSpan.Zero), + hash, + hash, + 2, + "key2"); Assert.True(!info1.Equals(info2)); Assert.True(!info2.Equals(info1)); Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); - } } } diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index 735e983d67b4c..6688dc7318b10 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -963,12 +963,14 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`public bool Equals(${naming.type(type.name)} other)`); w.scope('{', '}', () => { for (const property of properties) { + const a = naming.property(property.clientName); + const b = `other.${naming.property(property.clientName)}`; if (types.getDeclarationType(property.model, property.required, property.readonly) === "string") { - w.line(`if (!System.StringComparer.Ordinal.Equals(${naming.property(property.clientName)}, other.${naming.property(property.clientName)}))`); + w.line(`if (!System.StringComparer.Ordinal.Equals(${a}, ${b}))`); } else if (types.getDeclarationType(property.model, property.required, property.readonly).includes("[]")) { - w.line(`if (!Equals(${naming.property(property.clientName)}, other.${naming.property(property.clientName)}))`); + w.line(`if (!Equals(${a}, ${b}) && (${a} == null || ${b} == null || !System.Linq.Enumerable.SequenceEqual(${a}, ${b})))`); } else { - w.line(`if (!${naming.property(property.clientName)}.Equals(other.${naming.property(property.clientName)}))`); + w.line(`if (!${a}.Equals(${b}))`); } w.scope('{', '}', () => { w.line(`return false;`); From 2846ecad8b0835f40b365d605c070b120b942126 Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Mon, 30 Sep 2019 17:48:45 -0700 Subject: [PATCH 12/14] GetHashCode() returns false so revert - compare byte array by reference --- .../src/Generated/BlobRestClient.cs | 4 ++-- .../Azure.Storage.Blobs/tests/PageInfoTest.cs | 12 ++++++------ .../swagger/Generator/src/generator.ts | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index ba763c960168c..1f00f709cc126 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -17984,11 +17984,11 @@ public bool Equals(PageInfo other) { return false; } - if (!Equals(ContentHash, other.ContentHash) && (ContentHash == null || other.ContentHash == null || !System.Linq.Enumerable.SequenceEqual(ContentHash, other.ContentHash))) + if (!Equals(ContentHash, other.ContentHash)) { return false; } - if (!Equals(ContentCrc64, other.ContentCrc64) && (ContentCrc64 == null || other.ContentCrc64 == null || !System.Linq.Enumerable.SequenceEqual(ContentCrc64, other.ContentCrc64))) + if (!Equals(ContentCrc64, other.ContentCrc64)) { return false; } diff --git a/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs b/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs index 4d2c678ab92e7..b517d8afe3abb 100644 --- a/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs +++ b/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs @@ -63,7 +63,7 @@ public void EqualsReturnsTrueForNullValues() } [Test] - public void EqualsReturnsTrueIfCompareContentHashByValues() + public void EqualsReturnsFalseIfCompareContentHashByValues() { var hash1 = new byte[] { 1, 2, 3 }; var hash2 = new byte[] { 1, 2, 3 }; @@ -84,14 +84,14 @@ public void EqualsReturnsTrueIfCompareContentHashByValues() 1, "key1"); - Assert.True(info1.Equals(info2)); - Assert.True(info2.Equals(info1)); + Assert.True(!info1.Equals(info2)); + Assert.True(!info2.Equals(info1)); Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); } [Test] - public void EqualsReturnsTrueIfCompareContentCrc64ByValues() + public void EqualsReturnsFalseIfCompareContentCrc64ByValues() { var hash1 = new byte[] { 1, 2, 3 }; var hash2 = new byte[] { 1, 2, 3 }; @@ -112,8 +112,8 @@ public void EqualsReturnsTrueIfCompareContentCrc64ByValues() 1, "key1"); - Assert.True(info1.Equals(info2)); - Assert.True(info2.Equals(info1)); + Assert.True(!info1.Equals(info2)); + Assert.True(!info2.Equals(info1)); Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); } diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index 6688dc7318b10..69ea29c95afb7 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -968,7 +968,7 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType if (types.getDeclarationType(property.model, property.required, property.readonly) === "string") { w.line(`if (!System.StringComparer.Ordinal.Equals(${a}, ${b}))`); } else if (types.getDeclarationType(property.model, property.required, property.readonly).includes("[]")) { - w.line(`if (!Equals(${a}, ${b}) && (${a} == null || ${b} == null || !System.Linq.Enumerable.SequenceEqual(${a}, ${b})))`); + w.line(`if (!Equals(${a}, ${b}))`); } else { w.line(`if (!${a}.Equals(${b}))`); } From 9ca9e5b302baeb2556013389c935fc034d005ee5 Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Mon, 30 Sep 2019 23:08:34 -0700 Subject: [PATCH 13/14] Using StructuralComparisons.StructuralEqualityComparer for array comparison and hash code generation --- .../src/Generated/BlobRestClient.cs | 8 ++++---- .../Azure.Storage.Blobs/tests/PageInfoTest.cs | 16 ++++++++-------- .../swagger/Generator/src/generator.ts | 8 +++++--- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index 1f00f709cc126..79f9110e06c4d 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -17984,11 +17984,11 @@ public bool Equals(PageInfo other) { return false; } - if (!Equals(ContentHash, other.ContentHash)) + if (!System.Collections.StructuralComparisons.StructuralEqualityComparer.Equals(ContentHash, other.ContentHash)) { return false; } - if (!Equals(ContentCrc64, other.ContentCrc64)) + if (!System.Collections.StructuralComparisons.StructuralEqualityComparer.Equals(ContentCrc64, other.ContentCrc64)) { return false; } @@ -18019,8 +18019,8 @@ public override int GetHashCode() var hashCode = new Azure.Core.HashCodeBuilder(); hashCode.Add(ETag); hashCode.Add(LastModified); - hashCode.Add(ContentHash); - hashCode.Add(ContentCrc64); + hashCode.Add(System.Collections.StructuralComparisons.StructuralEqualityComparer.GetHashCode(ContentHash)); + hashCode.Add(System.Collections.StructuralComparisons.StructuralEqualityComparer.GetHashCode(ContentCrc64)); hashCode.Add(BlobSequenceNumber); if (EncryptionKeySha256 != null) { diff --git a/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs b/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs index b517d8afe3abb..5dc5bc623d049 100644 --- a/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs +++ b/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs @@ -63,7 +63,7 @@ public void EqualsReturnsTrueForNullValues() } [Test] - public void EqualsReturnsFalseIfCompareContentHashByValues() + public void EqualsReturnsTrueIfCompareContentHashByValues() { var hash1 = new byte[] { 1, 2, 3 }; var hash2 = new byte[] { 1, 2, 3 }; @@ -84,14 +84,14 @@ public void EqualsReturnsFalseIfCompareContentHashByValues() 1, "key1"); - Assert.True(!info1.Equals(info2)); - Assert.True(!info2.Equals(info1)); + Assert.True(info1.Equals(info2)); + Assert.True(info2.Equals(info1)); - Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); + Assert.AreEqual(info1.GetHashCode(), info2.GetHashCode()); } [Test] - public void EqualsReturnsFalseIfCompareContentCrc64ByValues() + public void EqualsReturnsTrueIfCompareContentCrc64ByValues() { var hash1 = new byte[] { 1, 2, 3 }; var hash2 = new byte[] { 1, 2, 3 }; @@ -112,10 +112,10 @@ public void EqualsReturnsFalseIfCompareContentCrc64ByValues() 1, "key1"); - Assert.True(!info1.Equals(info2)); - Assert.True(!info2.Equals(info1)); + Assert.True(info1.Equals(info2)); + Assert.True(info2.Equals(info1)); - Assert.AreNotEqual(info1.GetHashCode(), info2.GetHashCode()); + Assert.AreEqual(info1.GetHashCode(), info2.GetHashCode()); } [Test] diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index 69ea29c95afb7..b7ad56efa5e76 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -968,12 +968,12 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType if (types.getDeclarationType(property.model, property.required, property.readonly) === "string") { w.line(`if (!System.StringComparer.Ordinal.Equals(${a}, ${b}))`); } else if (types.getDeclarationType(property.model, property.required, property.readonly).includes("[]")) { - w.line(`if (!Equals(${a}, ${b}))`); + w.line(`if (!System.Collections.StructuralComparisons.StructuralEqualityComparer.Equals(${a}, ${b}))`); } else { w.line(`if (!${a}.Equals(${b}))`); } w.scope('{', '}', () => { - w.line(`return false;`); + w.line(`return false;`); }); } w.line(); @@ -997,8 +997,10 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType if (types.getDeclarationType(property.model, property.required, property.readonly) === "string") { w.line(`if (EncryptionKeySha256 != null)`) w.scope('{', '}', () => { - w.line(`hashCode.Add(${naming.property(property.clientName)}, System.StringComparer.Ordinal);`); + w.line(`hashCode.Add(${naming.property(property.clientName)}, System.StringComparer.Ordinal);`); }); + } else if (types.getDeclarationType(property.model, property.required, property.readonly).includes("[]")) { + w.line(`hashCode.Add(System.Collections.StructuralComparisons.StructuralEqualityComparer.GetHashCode(${naming.property(property.clientName)}));`); } else { w.line(`hashCode.Add(${naming.property(property.clientName)});`); } From c593e6c05ec8fac7af56c6ce9a0d5b537ae861f0 Mon Sep 17 00:00:00 2001 From: Shivangi Reja Date: Tue, 1 Oct 2019 12:21:15 -0700 Subject: [PATCH 14/14] Nit fixes --- .../src/Generated/BlobRestClient.cs | 97 ++++++++++--------- .../Azure.Storage.Blobs/tests/PageInfoTest.cs | 3 + .../src/Azure.Storage.Common.csproj | 2 +- .../swagger/Generator/src/generator.ts | 19 ++-- 4 files changed, 68 insertions(+), 53 deletions(-) diff --git a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs index 79f9110e06c4d..a039a6785db63 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/Generated/BlobRestClient.cs @@ -838,18 +838,18 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage GetAccountInfoAsync_Crea // Get response headers string _header; - Azure.Storage.Blobs.Models.SkuName _skuName = default; - Azure.Storage.Blobs.Models.AccountKind _accountKind = default; + Azure.Storage.Blobs.Models.SkuName skuName = default; + Azure.Storage.Blobs.Models.AccountKind accountKind = default; if (response.Headers.TryGetValue("x-ms-sku-name", out _header)) { - _skuName = Azure.Storage.Blobs.BlobRestClient.Serialization.ParseSkuName(_header); + skuName = Azure.Storage.Blobs.BlobRestClient.Serialization.ParseSkuName(_header); } if (response.Headers.TryGetValue("x-ms-account-kind", out _header)) { - _accountKind = (Azure.Storage.Blobs.Models.AccountKind)System.Enum.Parse(typeof(Azure.Storage.Blobs.Models.AccountKind), _header, false); + accountKind = (Azure.Storage.Blobs.Models.AccountKind)System.Enum.Parse(typeof(Azure.Storage.Blobs.Models.AccountKind), _header, false); } - Azure.Storage.Blobs.Models.AccountInfo _value = new Azure.Storage.Blobs.Models.AccountInfo(_skuName, _accountKind); + Azure.Storage.Blobs.Models.AccountInfo _value = new Azure.Storage.Blobs.Models.AccountInfo(skuName, accountKind); // Create the response Azure.Response _result = @@ -7819,38 +7819,38 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesAsync_CreateM // Get response headers string _header; - Azure.Core.Http.ETag _eTag = default; - System.DateTimeOffset _lastModified = default; - byte[] _contentHash = default; - byte[] _contentCrc64 = default; - long _blobSequenceNumber = default; - string _encryptionKeySha256 = default; + Azure.Core.Http.ETag eTag = default; + System.DateTimeOffset lastModified = default; + byte[] contentHash = default; + byte[] contentCrc64 = default; + long blobSequenceNumber = default; + string encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) { - _eTag = new Azure.Core.Http.ETag(_header); + eTag = new Azure.Core.Http.ETag(_header); } if (response.Headers.TryGetValue("Last-Modified", out _header)) { - _lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("Content-MD5", out _header)) { - _contentHash = System.Convert.FromBase64String(_header); + contentHash = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - _contentCrc64 = System.Convert.FromBase64String(_header); + contentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { - _blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("x-ms-encryption-key-sha256", out _header)) { - _encryptionKeySha256 = _header; + encryptionKeySha256 = _header; } - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _contentCrc64, _blobSequenceNumber, _encryptionKeySha256); + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(eTag, lastModified, contentHash, contentCrc64, blobSequenceNumber, encryptionKeySha256); // Create the response Azure.Response _result = @@ -8063,38 +8063,38 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage ClearPagesAsync_CreateMe // Get response headers string _header; - Azure.Core.Http.ETag _eTag = default; - System.DateTimeOffset _lastModified = default; - byte[] _contentHash = default; - byte[] _contentCrc64 = default; - long _blobSequenceNumber = default; - string _encryptionKeySha256 = default; + Azure.Core.Http.ETag eTag = default; + System.DateTimeOffset lastModified = default; + byte[] contentHash = default; + byte[] contentCrc64 = default; + long blobSequenceNumber = default; + string encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) { - _eTag = new Azure.Core.Http.ETag(_header); + eTag = new Azure.Core.Http.ETag(_header); } if (response.Headers.TryGetValue("Last-Modified", out _header)) { - _lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("Content-MD5", out _header)) { - _contentHash = System.Convert.FromBase64String(_header); + contentHash = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - _contentCrc64 = System.Convert.FromBase64String(_header); + contentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { - _blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("x-ms-encryption-key-sha256", out _header)) { - _encryptionKeySha256 = _header; + encryptionKeySha256 = _header; } - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _contentCrc64, _blobSequenceNumber, _encryptionKeySha256); + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(eTag, lastModified, contentHash, contentCrc64, blobSequenceNumber, encryptionKeySha256); // Create the response Azure.Response _result = @@ -8367,38 +8367,38 @@ internal static Azure.Core.Pipeline.HttpPipelineMessage UploadPagesFromUriAsync_ // Get response headers string _header; - Azure.Core.Http.ETag _eTag = default; - System.DateTimeOffset _lastModified = default; - byte[] _contentHash = default; - byte[] _contentCrc64 = default; - long _blobSequenceNumber = default; - string _encryptionKeySha256 = default; + Azure.Core.Http.ETag eTag = default; + System.DateTimeOffset lastModified = default; + byte[] contentHash = default; + byte[] contentCrc64 = default; + long blobSequenceNumber = default; + string encryptionKeySha256 = default; if (response.Headers.TryGetValue("ETag", out _header)) { - _eTag = new Azure.Core.Http.ETag(_header); + eTag = new Azure.Core.Http.ETag(_header); } if (response.Headers.TryGetValue("Last-Modified", out _header)) { - _lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + lastModified = System.DateTimeOffset.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("Content-MD5", out _header)) { - _contentHash = System.Convert.FromBase64String(_header); + contentHash = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-content-crc64", out _header)) { - _contentCrc64 = System.Convert.FromBase64String(_header); + contentCrc64 = System.Convert.FromBase64String(_header); } if (response.Headers.TryGetValue("x-ms-blob-sequence-number", out _header)) { - _blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); + blobSequenceNumber = long.Parse(_header, System.Globalization.CultureInfo.InvariantCulture); } if (response.Headers.TryGetValue("x-ms-encryption-key-sha256", out _header)) { - _encryptionKeySha256 = _header; + encryptionKeySha256 = _header; } - Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(_eTag, _lastModified, _contentHash, _contentCrc64, _blobSequenceNumber, _encryptionKeySha256); + Azure.Storage.Blobs.Models.PageInfo _value = new Azure.Storage.Blobs.Models.PageInfo(eTag, lastModified, contentHash, contentCrc64, blobSequenceNumber, encryptionKeySha256); // Create the response Azure.Response _result = @@ -12841,6 +12841,7 @@ internal AccountInfo( /// /// The instance to compare to. /// True if they're equal, false otherwise. + [System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))] public bool Equals(AccountInfo other) { if (!SkuName.Equals(other.SkuName)) @@ -12860,11 +12861,13 @@ public bool Equals(AccountInfo other) /// /// The instance to compare to. /// True if they're equal, false otherwise. + [System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))] public override bool Equals(object obj) => obj is AccountInfo && Equals((AccountInfo)obj); /// /// Get a hash code for the AccountInfo. /// + [System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))] public override int GetHashCode() { var hashCode = new Azure.Core.HashCodeBuilder(); @@ -17974,6 +17977,7 @@ internal PageInfo( /// /// The instance to compare to. /// True if they're equal, false otherwise. + [System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))] public bool Equals(PageInfo other) { if (!ETag.Equals(other.ETag)) @@ -18009,11 +18013,13 @@ public bool Equals(PageInfo other) /// /// The instance to compare to. /// True if they're equal, false otherwise. + [System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))] public override bool Equals(object obj) => obj is PageInfo && Equals((PageInfo)obj); /// /// Get a hash code for the PageInfo. /// + [System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))] public override int GetHashCode() { var hashCode = new Azure.Core.HashCodeBuilder(); @@ -18173,6 +18179,7 @@ internal PageRange( /// /// The instance to compare to. /// True if they're equal, false otherwise. + [System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))] public bool Equals(PageRange other) { if (!Start.Equals(other.Start)) @@ -18192,11 +18199,13 @@ public bool Equals(PageRange other) /// /// The instance to compare to. /// True if they're equal, false otherwise. + [System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))] public override bool Equals(object obj) => obj is PageRange && Equals((PageRange)obj); /// /// Get a hash code for the PageRange. /// + [System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))] public override int GetHashCode() { var hashCode = new Azure.Core.HashCodeBuilder(); diff --git a/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs b/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs index 5dc5bc623d049..c14bd21dca45b 100644 --- a/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs +++ b/sdk/storage/Azure.Storage.Blobs/tests/PageInfoTest.cs @@ -7,6 +7,9 @@ namespace Azure.Storage.Blobs.Tests { + /// + /// These tests are related to our generated struct behavior. + /// public class PageInfoTest { [Test] diff --git a/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj b/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj index 4a06440cb57ab..6f029aa958135 100644 --- a/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj +++ b/sdk/storage/Azure.Storage.Common/src/Azure.Storage.Common.csproj @@ -24,6 +24,6 @@ --> - + diff --git a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts index b7ad56efa5e76..cbcd7749cdacf 100644 --- a/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts +++ b/sdk/storage/Azure.Storage.Common/swagger/Generator/src/generator.ts @@ -592,7 +592,7 @@ function generateOperation(w: IndentWriter, serviceModel: IServiceModel, group: w.line(`string ${headerName};`); if (response.struct) { for (const header of headers) { - w.line(`${types.getDeclarationType(header.model, true, false, true)} _${naming.parameter(header.clientName)} = default;`); + w.line(`${types.getDeclarationType(header.model, true, false, true)} ${naming.parameter(header.clientName)} = default;`); } } for (const header of headers) { @@ -610,7 +610,7 @@ function generateOperation(w: IndentWriter, serviceModel: IServiceModel, group: w.line(`if (${responseName}.Headers.TryGetValue("${header.name}", out ${headerName}))`); w.scope('{', '}', () => { if (response.struct) { - w.write(`_${naming.parameter(header.clientName)} = `); + w.write(`${naming.parameter(header.clientName)} = `); } else { w.write(`${valueName}.${naming.pascalCase(header.clientName)} = `); } @@ -628,11 +628,11 @@ function generateOperation(w: IndentWriter, serviceModel: IServiceModel, group: } if (response.struct) { w.line(); - const Separator = IndentWriter.createFenceposter(); + const separator = IndentWriter.createFenceposter(); w.write(`${types.getName(model)} ${valueName} = new ${types.getName(model)}(`); for (const header of headers) { - if (Separator()) { w.write(`, `); } - w.write(`_${naming.parameter(header.clientName)}`); + if (separator()) { w.write(`, `); } + w.write(`${naming.parameter(header.clientName)}`); } w.write(`);`); w.line(); @@ -960,6 +960,7 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`/// `); w.line(`/// The instance to compare to.`); w.line(`/// True if they're equal, false otherwise.`); + w.line(`[System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))]`); w.line(`public bool Equals(${naming.type(type.name)} other)`); w.scope('{', '}', () => { for (const property of properties) { @@ -985,17 +986,19 @@ function generateObject(w: IndentWriter, model: IServiceModel, type: IObjectType w.line(`/// `); w.line(`/// The instance to compare to.`); w.line(`/// True if they're equal, false otherwise.`); + w.line(`[System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))]`); w.line(`public override bool Equals(object obj) => obj is ${naming.type(type.name)} && Equals((${naming.type(type.name)})obj);`); w.line(); w.line(`/// `) w.line(`/// Get a hash code for the ${naming.type(type.name)}.`); w.line(`/// `); + w.line(`[System.ComponentModel.EditorBrowsable((System.ComponentModel.EditorBrowsableState.Never))]`); w.line(`public override int GetHashCode()`); w.scope('{', '}', () => { w.line(`var hashCode = new Azure.Core.HashCodeBuilder();`); for (const property of properties) { if (types.getDeclarationType(property.model, property.required, property.readonly) === "string") { - w.line(`if (EncryptionKeySha256 != null)`) + w.line(`if (${naming.property(property.clientName)} != null)`) w.scope('{', '}', () => { w.line(`hashCode.Add(${naming.property(property.clientName)}, System.StringComparer.Ordinal);`); }); @@ -1313,10 +1316,10 @@ function generateDeserialize(w: IndentWriter, service: IService, type: IObjectTy } } if (type.struct) { - const Separator = IndentWriter.createFenceposter(); + const separator = IndentWriter.createFenceposter(); w.write(`${types.getName(type)} ${valueName} = new ${types.getName(type)}(`); for (const property of properties) { - if (Separator()) { w.write(`, `); } + if (separator()) { w.write(`, `); } w.write(`${naming.parameter(property.clientName)}`); } w.write(`);`);