public async Task<long> NextId() { lock (nextLock) { if (last < max) { return ++last; } } await semaphore.WaitAsync(); try { lock (nextLock) { if (last < max) { return ++last; } } for (var tries = 0; tries < 10; ++tries) { HttpStatusCode saveResultCode; long oldMax, newMax; var hiEntity = await HiloTable.RetreiveAsync(tableName, "hi"); if (hiEntity == null) { oldMax = 0; newMax = chunkSize; hiEntity = new DynamicTableEntity(tableName, "hi"); hiEntity["max"] = new EntityProperty(newMax); saveResultCode = await HiloTable.InsertAsync(hiEntity); } else { oldMax = hiEntity["max"].Int64Value.GetValueOrDefault(0); newMax = oldMax + chunkSize; hiEntity["max"] = new EntityProperty(newMax); saveResultCode = await HiloTable.ReplaceAsync(hiEntity); } if (saveResultCode == HttpStatusCode.Created || saveResultCode == HttpStatusCode.NoContent) { lock (nextLock) { last = oldMax; max = newMax; return ++last; } } } throw new Exception( string.Format( "Could not allocate id range for table '{0}' with chunkSize={1} due to high contention.\r\nConsider increasing the chunk size", tableName, chunkSize)); } finally { semaphore.Release(); } }
void UpdatingForExistingStream() { var partition = new Partition(Table, Id + ".c"); var properties = new Dictionary<string, EntityProperty> { {"Created", new EntityProperty(DateTimeOffset.Now)}, {"Active", new EntityProperty(true)} }; Stream.Provision(partition, StreamProperties.From(properties)); Console.WriteLine("Stream metadata specified for stream in partition '{0}'", partition); var stream = Stream.Open(partition); Print(stream.Properties); properties["Active"] = new EntityProperty(false); Stream.SetProperties(stream, StreamProperties.From(properties)); Console.WriteLine("Updated stream metadata in partition '{0}'", partition); stream = Stream.Open(partition); Print(stream.Properties); }
private object GetValue(EntityProperty property) { switch (property.PropertyType) { case EdmType.Binary: return property.BinaryValue; case EdmType.Boolean: return property.BooleanValue; case EdmType.DateTime: return property.DateTimeOffsetValue; case EdmType.Double: return property.DoubleValue; case EdmType.Guid: return property.GuidValue; case EdmType.Int32: return property.Int32Value; case EdmType.Int64: return property.Int64Value; case EdmType.String: return property.StringValue; default: return ""; } }
public void Create_EntityProperty_CanConvert() { // Act IConverter<EntityProperty, EntityProperty> converter = TToEntityPropertyConverterFactory.Create<EntityProperty>(); // Assert Assert.NotNull(converter); EntityProperty expected = new EntityProperty(1); EntityProperty property = converter.Convert(expected); Assert.Same(expected, property); }
public void CreateInstanceFromProperties_TargetTypeDecoratedWithETagAttribute_ETagSetCorrectly() { var genericEntity = new GenericTableEntity { ETag = "tag" }; var entityProperties = new Dictionary<string, EntityProperty>(); entityProperties["Age"] = new EntityProperty( 42 ); genericEntity.ReadEntity( entityProperties, null ); var item = genericEntity.ConvertTo<DecoratedItemWithETag>(); Assert.AreEqual( "tag", item.ETag, "Incorrect ETag" ); }
public void CreateInstanceFromProperties_TargetTypeDecoratedWithTimestampAttribute_TimestampSetCorrectly() { var dt = DateTime.Now; var genericEntity = new GenericTableEntity { Timestamp = dt }; var entityProperties = new Dictionary<string, EntityProperty>(); entityProperties["Age"] = new EntityProperty( 42 ); genericEntity.ReadEntity( entityProperties, null ); var item = genericEntity.ConvertTo<DecoratedItemWithTimestamp>(); Assert.AreEqual( dt, item.Timestamp, "Incorrect Timestamp" ); }
public void CreateInstanceFromProperties_TargetTypeDecoratedWithRowAndPartitionKeyAttributes_RowAndPartitionKeySetCorrectly() { var genericEntity = new GenericTableEntity { PartitionKey = "foo", RowKey = "bar" }; var entityProperties = new Dictionary<string, EntityProperty>(); entityProperties["Age"] = new EntityProperty( 42 ); genericEntity.ReadEntity( entityProperties, null ); var item = genericEntity.ConvertTo<DecoratedItem>(); Assert.AreEqual( "foo", item.Id, "Incorrect partition key" ); Assert.AreEqual( "bar", item.Name, "Incorrect row key" ); }
public static DynamicTableEntity ToDynamicEntity(this JsonObject oneObject) { if (oneObject == null) throw new ArgumentNullException("oneObject"); var dict = new Dictionary<string, EntityProperty>(); foreach (var item in oneObject) { if (item.Key.Equals(EntityConstants.PartitionKey.ToLowerInvariant()) || item.Key.Equals(EntityConstants.RowKey.ToLowerInvariant()) || item.Key.Equals("etag")) continue; EntityProperty property = null; var type = item.Value.GetType(); var value = item.Value; if (type == typeof(string)) property = new EntityProperty((string)value); else if (type == typeof(int)) property = new EntityProperty((int)value); else if (type == typeof(long)) property = new EntityProperty((long)value); else if (type == typeof(double)) property = new EntityProperty((double)value); else if (type == typeof(Guid)) property = new EntityProperty((Guid)value); else if (type == typeof(bool)) property = new EntityProperty((bool)value); else if (type.IsEnum) { var typeCode = ((Enum)value).GetTypeCode(); property = typeCode <= TypeCode.Int32 ? new EntityProperty(Convert.ToInt32(value, CultureInfo.InvariantCulture)) : new EntityProperty(Convert.ToInt64(value, CultureInfo.InvariantCulture)); } else if (type == typeof(byte[])) property = new EntityProperty((byte[])value); else if (type == typeof(object[])) property = new EntityProperty(JsonConvert.SerializeObject(value)); if (property != null) dict.Add(item.Key, property); } var etag = oneObject.ContainsKey("etag") ? oneObject["etag"].ToString() : null; return new DynamicTableEntity("PK", oneObject.Id, etag, dict); }
public void Add(string key, EntityProperty value) { internalProperties.Add(key, value); }
protected virtual MemoryStream ReadBinaryEntityProperty(EntityProperty property) { return new MemoryStream(property.BinaryValue, false); }
public static DynamicTableEntity CreateTableEntity(this CloudEventEntry entry) { var dictionary = new Dictionary<string, EntityProperty>(); dictionary.Add("EventId", new EntityProperty(entry.EventId)); dictionary.Add("EventDate", new EntityProperty(entry.EventDate)); dictionary.Add("Keywords", new EntityProperty(entry.Keywords)); dictionary.Add("ProviderId", new EntityProperty(entry.ProviderId)); dictionary.Add("ProviderName", new EntityProperty(entry.ProviderName)); dictionary.Add("InstanceName", new EntityProperty(entry.InstanceName)); dictionary.Add("Level", new EntityProperty(entry.Level)); if (entry.Message != null) { dictionary.Add("Message", new EntityProperty(Normalize(entry.Message))); } dictionary.Add("Opcode", new EntityProperty(entry.Opcode)); dictionary.Add("Task", new EntityProperty(entry.Task)); dictionary.Add("Version", new EntityProperty(entry.Version)); // Create a "Payload" if (entry.Payload != null && entry.Payload.Count > 0) { var json = EventEntryUtil.JsonSerializePayload(entry.Payload); if (json.Length > MaxStringLength) { dictionary.Add("Payload", new EntityProperty("{ 'payload_serialization_error':'The payload is too big to serialize.' }")); } else { dictionary.Add("Payload", new EntityProperty(json)); foreach (var item in entry.Payload.Take(MaxPayloadItems)) { var value = item.Value; if (value != null) { EntityProperty property = null; var type = value.GetType(); if (type == typeof(string)) { property = new EntityProperty((string)value); } else if (type == typeof(int)) { property = new EntityProperty((int)value); } else if (type == typeof(long)) { property = new EntityProperty((long)value); } else if (type == typeof(double)) { property = new EntityProperty((double)value); } else if (type == typeof(Guid)) { property = new EntityProperty((Guid)value); } else if (type == typeof(bool)) { property = new EntityProperty((bool)value); } else if (type.IsEnum) { var typeCode = ((Enum)value).GetTypeCode(); if (typeCode <= TypeCode.Int32) { property = new EntityProperty(Convert.ToInt32(value, CultureInfo.InvariantCulture)); } else { property = new EntityProperty(Convert.ToInt64(value, CultureInfo.InvariantCulture)); } } else if (type == typeof(byte[])) { property = new EntityProperty((byte[])value); } //// TODO: add & review DateTimeOffset if it's supported if (property != null) { dictionary.Add(string.Format(CultureInfo.InvariantCulture, "Payload_{0}", item.Key), property); } } } } } return new DynamicTableEntity(entry.PartitionKey, entry.RowKey, null, dictionary); }
private static Task<ClaimsPrincipal> SubjectDeserializer(EntityProperty property) { return Task.FromResult(new ClaimsPrincipal(new ClaimsIdentity( JArray.Parse(property.StringValue) .Select(j => new Claim(j["Type"].ToObject<string>(), j["Value"].ToObject<string>()))))); }
internal static EntityProperty DeepClone(EntityProperty property) { EdmType propertyType = property.PropertyType; switch (propertyType) { case EdmType.Binary: byte[] existingBytes = property.BinaryValue; byte[] clonedBytes; if (existingBytes == null) { clonedBytes = null; } else { clonedBytes = new byte[existingBytes.LongLength]; Array.Copy(existingBytes, clonedBytes, existingBytes.LongLength); } return new EntityProperty(clonedBytes); case EdmType.Boolean: return new EntityProperty(property.BooleanValue); case EdmType.DateTime: return new EntityProperty(property.DateTime); case EdmType.Double: return new EntityProperty(property.DoubleValue); case EdmType.Guid: return new EntityProperty(property.GuidValue); case EdmType.Int32: return new EntityProperty(property.Int32Value); case EdmType.Int64: return new EntityProperty(property.Int64Value); case EdmType.String: return new EntityProperty(property.StringValue); default: string message = String.Format(CultureInfo.CurrentCulture, "Unknown PropertyType {0}.", propertyType); throw new NotSupportedException(message); } }
internal byte[] DecryptMetadataAndReturnCEK(string partitionKey, string rowKey, EntityProperty encryptionKeyProperty, EntityProperty propertyDetailsProperty, out EncryptionData encryptionData) { // Throw if neither the key nor the resolver are set. if (this.Key == null && this.KeyResolver == null) { throw new StorageException(SR.KeyAndResolverMissingError, null) { IsRetryable = false }; } try { encryptionData = JsonConvert.DeserializeObject<EncryptionData>(encryptionKeyProperty.StringValue); CommonUtility.AssertNotNull("ContentEncryptionIV", encryptionData.ContentEncryptionIV); CommonUtility.AssertNotNull("EncryptedKey", encryptionData.WrappedContentKey.EncryptedKey); // Throw if the encryption protocol on the entity doesn't match the version that this client library understands // and is able to decrypt. if (encryptionData.EncryptionAgent.Protocol != Constants.EncryptionConstants.EncryptionProtocolV1) { throw new StorageException(SR.EncryptionProtocolVersionInvalid, null) { IsRetryable = false }; } byte[] contentEncryptionKey = null; // 1. Invoke the key resolver if specified to get the key. If the resolver is specified but does not have a // mapping for the key id, an error should be thrown. This is important for key rotation scenario. // 2. If resolver is not specified but a key is specified, match the key id on the key and and use it. // Calling UnwrapKeyAsync synchronously is fine because for the storage client scenario, unwrap happens // locally. No service call is made. if (this.KeyResolver != null) { IKey keyEncryptionKey = this.KeyResolver.ResolveKeyAsync(encryptionData.WrappedContentKey.KeyId, CancellationToken.None).Result; CommonUtility.AssertNotNull("keyEncryptionKey", keyEncryptionKey); contentEncryptionKey = keyEncryptionKey.UnwrapKeyAsync(encryptionData.WrappedContentKey.EncryptedKey, encryptionData.WrappedContentKey.Algorithm, CancellationToken.None).Result; } else { if (this.Key.Kid == encryptionData.WrappedContentKey.KeyId) { contentEncryptionKey = this.Key.UnwrapKeyAsync(encryptionData.WrappedContentKey.EncryptedKey, encryptionData.WrappedContentKey.Algorithm, CancellationToken.None).Result; } else { throw new StorageException(SR.KeyMismatch, null) { IsRetryable = false }; } } // Decrypt the property details set and add it to entity properties. #if WINDOWS_DESKTOP && !WINDOWS_PHONE using (AesCryptoServiceProvider myAes = new AesCryptoServiceProvider()) { using (SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider()) #else using (AesManaged myAes = new AesManaged()) { using (SHA256Managed sha256 = new SHA256Managed()) #endif { byte[] metadataIV = sha256.ComputeHash(CommonUtility.BinaryAppend(encryptionData.ContentEncryptionIV, Encoding.UTF8.GetBytes(string.Join(partitionKey, rowKey, Constants.EncryptionConstants.TableEncryptionPropertyDetails)))); Array.Resize<byte>(ref metadataIV, 16); myAes.IV = metadataIV; myAes.Key = contentEncryptionKey; using (ICryptoTransform transform = myAes.CreateDecryptor()) { byte[] src = propertyDetailsProperty.BinaryValue; propertyDetailsProperty.BinaryValue = transform.TransformFinalBlock(src, 0, src.Length); } } } return contentEncryptionKey; } catch (JsonException ex) { throw new StorageException(SR.EncryptionMetadataError, ex) { IsRetryable = false }; } catch (StorageException) { throw; } catch (Exception ex) { throw new StorageException(SR.DecryptionLogicError, ex) { IsRetryable = false }; } }
public bool Equals(EntityProperty other) { throw new System.NotImplementedException(); }
public virtual void Add([NotNull] string key, DateTimeOffset value) { Check.NotNull(key, "key"); _values[key] = new EntityProperty(value); }
public virtual void Add([NotNull] string key, [CanBeNull] string value) { Check.NotNull(key, "key"); _values[key] = new EntityProperty(value); }
public virtual void ReadEntity(IDictionary <string, EntityProperty> properties, OperationContext operationContext) { #if RT IEnumerable <PropertyInfo> objectProperties = this.GetType().GetRuntimeProperties(); #else IEnumerable <PropertyInfo> objectProperties = this.GetType().GetProperties(); #endif foreach (PropertyInfo property in objectProperties) { // reserved properties if (property.Name == TableConstants.PartitionKey || property.Name == TableConstants.RowKey || property.Name == TableConstants.Timestamp || property.Name == "ETag") { continue; } // Enforce public getter / setter #if RT if (property.SetMethod == null || !property.SetMethod.IsPublic || property.GetMethod == null || !property.GetMethod.IsPublic) #else if (property.GetSetMethod() == null || !property.GetSetMethod().IsPublic || property.GetGetMethod() == null || !property.GetGetMethod().IsPublic) #endif { continue; } // only proceed with properties that have a corresponding entry in the dictionary if (!properties.ContainsKey(property.Name)) { continue; } EntityProperty entityProperty = properties[property.Name]; if (entityProperty.IsNull) { property.SetValue(this, null, null); } else { switch (entityProperty.PropertyType) { case EdmType.String: if (property.PropertyType != typeof(string) && property.PropertyType != typeof(String)) { continue; } property.SetValue(this, entityProperty.StringValue, null); break; case EdmType.Binary: if (property.PropertyType != typeof(byte[])) { continue; } property.SetValue(this, entityProperty.BinaryValue, null); break; case EdmType.Boolean: if (property.PropertyType != typeof(bool) && property.PropertyType != typeof(Boolean) && property.PropertyType != typeof(Boolean?) && property.PropertyType != typeof(bool?)) { continue; } property.SetValue(this, entityProperty.BooleanValue, null); break; case EdmType.DateTime: if (property.PropertyType == typeof(DateTime)) { property.SetValue(this, entityProperty.DateTimeOffsetValue.Value.UtcDateTime, null); } else if (property.PropertyType == typeof(DateTime?)) { property.SetValue(this, entityProperty.DateTimeOffsetValue.HasValue ? entityProperty.DateTimeOffsetValue.Value.UtcDateTime : (DateTime?)null, null); } else if (property.PropertyType == typeof(DateTimeOffset)) { property.SetValue(this, entityProperty.DateTimeOffsetValue.Value, null); } else if (property.PropertyType == typeof(DateTimeOffset?)) { property.SetValue(this, entityProperty.DateTimeOffsetValue, null); } break; case EdmType.Double: if (property.PropertyType != typeof(double) && property.PropertyType != typeof(Double) && property.PropertyType != typeof(Double?) && property.PropertyType != typeof(double?)) { continue; } property.SetValue(this, entityProperty.DoubleValue, null); break; case EdmType.Guid: if (property.PropertyType != typeof(Guid) && property.PropertyType != typeof(Guid?)) { continue; } property.SetValue(this, entityProperty.GuidValue, null); break; case EdmType.Int32: if (property.PropertyType != typeof(int) && property.PropertyType != typeof(Int32) && property.PropertyType != typeof(Int32?) && property.PropertyType != typeof(int?)) { continue; } property.SetValue(this, entityProperty.Int32Value, null); break; case EdmType.Int64: if (property.PropertyType != typeof(long) && property.PropertyType != typeof(Int64) && property.PropertyType != typeof(long?) && property.PropertyType != typeof(Int64?)) { continue; } property.SetValue(this, entityProperty.Int64Value, null); break; } } } }
/// <summary> /// Traverses object graph, flattens and converts all nested (and not nested) properties to EntityProperties, stores them in the property dictionary. /// The keys are constructed by appending the names of the properties visited during pre-order depth first traversal from root to each end node property delimited by '.'. /// Allows complex objects to be stored in persistent storage systems or passed between web services in a generic way. /// </summary> /// <param name="propertyDictionary">The property dictionary.</param> /// <param name="current">The current object.</param> /// <param name="objectPath">The object path.</param> /// <param name="antecedents">The antecedents of current object, used to detect circular references in object graph.</param> /// <param name="entityPropertyConverterOptions">A <see cref="EntityPropertyConverterOptions"/> object that specifies options for the entity property conversion.</param> /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param> /// <returns>The <see cref="bool"/> to indicate success of conversion to flattened EntityPropertyDictionary.</returns> private static bool Flatten( Dictionary <string, EntityProperty> propertyDictionary, object current, string objectPath, HashSet <object> antecedents, EntityPropertyConverterOptions entityPropertyConverterOptions, OperationContext operationContext) { if (current == null) { return(true); } Type type = current.GetType(); EntityProperty entityProperty = CreateEntityPropertyWithType(current, type); if (entityProperty != null) { propertyDictionary.Add(objectPath, entityProperty); return(true); } #if WINDOWS_RT IEnumerable <PropertyInfo> propertyInfos = type.GetRuntimeProperties(); #elif NETCORE IEnumerable <PropertyInfo> propertyInfos = type.GetTypeInfo().GetAllProperties(); #else IEnumerable <PropertyInfo> propertyInfos = type.GetProperties(); #endif if (!propertyInfos.Any()) { throw new SerializationException(string.Format(CultureInfo.InvariantCulture, SR.UnsupportedPropertyTypeForEntityPropertyConversion, type, objectPath)); } bool isAntecedent = false; #if WINDOWS_RT || NETCORE if (!type.GetTypeInfo().IsValueType) #else if (!type.IsValueType) #endif { if (antecedents.Contains(current)) { throw new SerializationException(string.Format(CultureInfo.InvariantCulture, SR.RecursiveReferencedObject, objectPath, type)); } antecedents.Add(current); isAntecedent = true; } string propertyNameDelimiter = entityPropertyConverterOptions != null ? entityPropertyConverterOptions.PropertyNameDelimiter : DefaultPropertyNameDelimiter; bool success = propertyInfos .Where(propertyInfo => !ShouldSkip(propertyInfo, objectPath, operationContext)) .All(propertyInfo => { if (propertyInfo.Name.Contains(propertyNameDelimiter)) { throw new SerializationException( string.Format(CultureInfo.InvariantCulture, SR.PropertyDelimiterExistsInPropertyName, propertyNameDelimiter, propertyInfo.Name, objectPath)); } return(Flatten( propertyDictionary, propertyInfo.GetValue(current, index: null), string.IsNullOrWhiteSpace(objectPath) ? propertyInfo.Name : objectPath + propertyNameDelimiter + propertyInfo.Name, antecedents, entityPropertyConverterOptions, operationContext)); }); if (isAntecedent) { antecedents.Remove(current); } return(success); }
//public void refreshEvalData(string productId, int testKeyId, AzureData.saveKeyDataObj[] pcEvals) { // if (dataObj.Any(st => st.productId == productId && st.testKeyId == testKeyId)) return; // dataObj.Add(new azure.hmanEvalController.student { productId = productId, testKeyId = testKeyId }); //} protected override void afterRead(string key, EntityProperty prop) { switch (key) { case "data": data = prop.StringValue; break; default: base.afterRead(key, prop); break; } }
internal static void WriteTimestamp(IDictionary<string, EntityProperty> prop, string key, DateTimeOffset val) { Debug.Assert(!prop.ContainsKey(key)); prop[key] = new EntityProperty(val); }
private object GetValue(EntityProperty property) { switch (property.PropertyType) { case EdmType.Binary: return property.BinaryValue; case EdmType.Boolean: return property.BooleanValue; case EdmType.DateTime: return property.DateTimeOffsetValue; case EdmType.Double: return property.DoubleValue; case EdmType.Guid: return property.GuidValue; case EdmType.Int32: return property.Int32Value; case EdmType.Int64: return property.Int64Value; case EdmType.String: return property.StringValue; default: throw new Exception("not supported " + property.PropertyType); } }
private static void ReflectionRead(object entity, IDictionary <string, EntityProperty> properties, OperationContext operationContext) { #if WINDOWS_RT IEnumerable <PropertyInfo> objectProperties = entity.GetType().GetRuntimeProperties(); #elif NETCORE IEnumerable <PropertyInfo> objectProperties = entity.GetType().GetTypeInfo().GetAllProperties(); #else IEnumerable <PropertyInfo> objectProperties = entity.GetType().GetProperties(); #endif foreach (PropertyInfo property in objectProperties) { if (ShouldSkipProperty(property, operationContext)) { continue; } // only proceed with properties that have a corresponding entry in the dictionary if (!properties.ContainsKey(property.Name)) { Logger.LogInformational(operationContext, SR.TraceMissingDictionaryEntry, property.Name); continue; } EntityProperty entityProperty = properties[property.Name]; if (entityProperty.IsNull) { property.SetValue(entity, null, null); } else { switch (entityProperty.PropertyType) { case EdmType.String: if (property.PropertyType != typeof(string)) { continue; } property.SetValue(entity, entityProperty.StringValue, null); break; case EdmType.Binary: if (property.PropertyType != typeof(byte[])) { continue; } property.SetValue(entity, entityProperty.BinaryValue, null); break; case EdmType.Boolean: if (property.PropertyType != typeof(bool) && property.PropertyType != typeof(bool?)) { continue; } property.SetValue(entity, entityProperty.BooleanValue, null); break; case EdmType.DateTime: if (property.PropertyType == typeof(DateTime)) { property.SetValue(entity, entityProperty.DateTimeOffsetValue.Value.UtcDateTime, null); } else if (property.PropertyType == typeof(DateTime?)) { property.SetValue(entity, entityProperty.DateTimeOffsetValue.HasValue ? entityProperty.DateTimeOffsetValue.Value.UtcDateTime : (DateTime?)null, null); } else if (property.PropertyType == typeof(DateTimeOffset)) { property.SetValue(entity, entityProperty.DateTimeOffsetValue.Value, null); } else if (property.PropertyType == typeof(DateTimeOffset?)) { property.SetValue(entity, entityProperty.DateTimeOffsetValue, null); } break; case EdmType.Double: if (property.PropertyType != typeof(double) && property.PropertyType != typeof(double?)) { continue; } property.SetValue(entity, entityProperty.DoubleValue, null); break; case EdmType.Guid: if (property.PropertyType != typeof(Guid) && property.PropertyType != typeof(Guid?)) { continue; } property.SetValue(entity, entityProperty.GuidValue, null); break; case EdmType.Int32: if (property.PropertyType != typeof(int) && property.PropertyType != typeof(int?)) { continue; } property.SetValue(entity, entityProperty.Int32Value, null); break; case EdmType.Int64: if (property.PropertyType != typeof(long) && property.PropertyType != typeof(long?)) { continue; } property.SetValue(entity, entityProperty.Int64Value, null); break; } } } }
public void EntityPropertyTests() { Random rand = new Random(); // Binary byte[] bytes = new byte[1024]; rand.NextBytes(bytes); // Ctor EntityProperty binProp = EntityProperty.GeneratePropertyForByteArray(bytes); Assert.AreEqual(binProp.BinaryValue, bytes); // Setter byte[] bytes2 = new byte[1024]; rand.NextBytes(bytes2); binProp.BinaryValue = bytes2; Assert.AreEqual(binProp.BinaryValue, bytes2); // Null binProp.BinaryValue = null; Assert.AreEqual(binProp.BinaryValue, null); // bool bool boolVal = true; // Ctor EntityProperty boolProp = EntityProperty.GeneratePropertyForBool(boolVal); Assert.AreEqual(boolProp.BooleanValue, boolVal); // Setter bool boolVal2 = true; boolProp.BooleanValue = boolVal2; Assert.AreEqual(boolProp.BooleanValue, boolVal2); // DateTimeOffset DateTimeOffset dto = DateTimeOffset.Now; // Ctor EntityProperty dtoProp = EntityProperty.GeneratePropertyForDateTimeOffset(dto); Assert.AreEqual(dtoProp.DateTimeOffsetValue, dto); // Setter DateTimeOffset dto2 = DateTimeOffset.UtcNow; dtoProp.DateTimeOffsetValue = dto2; Assert.AreEqual(dtoProp.DateTimeOffsetValue, dto2); // Null DateTimeOffset?dto3 = (DateTimeOffset?)null; dtoProp.DateTimeOffsetValue = dto3; Assert.AreEqual(dtoProp.DateTimeOffsetValue, dto3); // double double doubleVal = 1234.4564; // Ctor EntityProperty doubleProp = EntityProperty.GeneratePropertyForDouble(doubleVal); Assert.AreEqual(doubleProp.DoubleValue, doubleVal); // Setter double doubleVal2 = 8979654.35454; doubleProp.DoubleValue = doubleVal2; Assert.AreEqual(doubleProp.DoubleValue, doubleVal2); // Guid Guid guidVal = new Guid(); // Ctor EntityProperty guidProp = EntityProperty.GeneratePropertyForGuid(guidVal); Assert.AreEqual(guidProp.GuidValue, guidVal); // Setter Guid guidVal2 = new Guid(); guidProp.GuidValue = guidVal2; Assert.AreEqual(guidProp.GuidValue, guidVal2); // int int intVal = 1234; // Ctor EntityProperty intProp = EntityProperty.GeneratePropertyForInt(intVal); Assert.AreEqual(intProp.Int32Value, intVal); // Setter int intVal2 = 8979654; intProp.Int32Value = intVal2; Assert.AreEqual(intProp.Int32Value, intVal2); // long long longVal = 123456789012; // Ctor EntityProperty longProp = EntityProperty.GeneratePropertyForLong(longVal); Assert.AreEqual(longProp.Int64Value, longVal); // Setter long longVal2 = 56789012345; longProp.Int64Value = longVal2; Assert.AreEqual(longProp.Int64Value, longVal2); // string string string1 = "abcdefghijklmnop"; // Ctor EntityProperty stringProp = EntityProperty.GeneratePropertyForString(string1); Assert.AreEqual(stringProp.StringValue, string1); // Setter string string2 = "1234567890"; stringProp.StringValue = string2; Assert.AreEqual(stringProp.StringValue, string2); // Null string string3 = null; stringProp.StringValue = string3; Assert.AreEqual(stringProp.StringValue, string3); }
internal byte[] DecryptMetadataAndReturnCEK(string partitionKey, string rowKey, EntityProperty encryptionKeyProperty, EntityProperty propertyDetailsProperty, out EncryptionData encryptionData) { // Throw if neither the key nor the resolver are set. if (this.Key == null && this.KeyResolver == null) { throw new StorageException(SR.KeyAndResolverMissingError, null) { IsRetryable = false }; } try { encryptionData = JsonConvert.DeserializeObject <EncryptionData>(encryptionKeyProperty.StringValue); CommonUtility.AssertNotNull("ContentEncryptionIV", encryptionData.ContentEncryptionIV); CommonUtility.AssertNotNull("EncryptedKey", encryptionData.WrappedContentKey.EncryptedKey); // Throw if the encryption protocol on the entity doesn't match the version that this client library understands // and is able to decrypt. if (encryptionData.EncryptionAgent.Protocol != Constants.EncryptionConstants.EncryptionProtocolV1) { throw new StorageException(SR.EncryptionProtocolVersionInvalid, null) { IsRetryable = false }; } byte[] contentEncryptionKey = null; // 1. Invoke the key resolver if specified to get the key. If the resolver is specified but does not have a // mapping for the key id, an error should be thrown. This is important for key rotation scenario. // 2. If resolver is not specified but a key is specified, match the key id on the key and and use it. // Calling UnwrapKeyAsync synchronously is fine because for the storage client scenario, unwrap happens // locally. No service call is made. if (this.KeyResolver != null) { IKey keyEncryptionKey = this.KeyResolver.ResolveKeyAsync(encryptionData.WrappedContentKey.KeyId, CancellationToken.None).Result; CommonUtility.AssertNotNull("keyEncryptionKey", keyEncryptionKey); contentEncryptionKey = keyEncryptionKey.UnwrapKeyAsync(encryptionData.WrappedContentKey.EncryptedKey, encryptionData.WrappedContentKey.Algorithm, CancellationToken.None).Result; } else { if (this.Key.Kid == encryptionData.WrappedContentKey.KeyId) { contentEncryptionKey = this.Key.UnwrapKeyAsync(encryptionData.WrappedContentKey.EncryptedKey, encryptionData.WrappedContentKey.Algorithm, CancellationToken.None).Result; } else { throw new StorageException(SR.KeyMismatch, null) { IsRetryable = false }; } } // Decrypt the property details set and add it to entity properties. #if WINDOWS_DESKTOP && !WINDOWS_PHONE using (AesCryptoServiceProvider myAes = new AesCryptoServiceProvider()) { using (SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider()) #else using (AesManaged myAes = new AesManaged()) { using (SHA256Managed sha256 = new SHA256Managed()) #endif { byte[] metadataIV = sha256.ComputeHash(CommonUtility.BinaryAppend(encryptionData.ContentEncryptionIV, Encoding.UTF8.GetBytes(string.Join(partitionKey, rowKey, Constants.EncryptionConstants.TableEncryptionPropertyDetails)))); Array.Resize <byte>(ref metadataIV, 16); myAes.IV = metadataIV; myAes.Key = contentEncryptionKey; using (ICryptoTransform transform = myAes.CreateDecryptor()) { byte[] src = propertyDetailsProperty.BinaryValue; propertyDetailsProperty.BinaryValue = transform.TransformFinalBlock(src, 0, src.Length); } } } return(contentEncryptionKey); } catch (JsonException ex) { throw new StorageException(SR.EncryptionMetadataError, ex) { IsRetryable = false }; } catch (StorageException) { throw; } catch (Exception ex) { throw new StorageException(SR.DecryptionLogicError, ex) { IsRetryable = false }; } }
internal static void WriteString(IDictionary<string, EntityProperty> prop, string key, string val) { Debug.Assert(!prop.ContainsKey(key)); prop[key] = new EntityProperty(val); }
private DynamicTableEntity getUpdatedEntity(ScheduledTaskUpdate taskUpdate) { DynamicTableEntity ent = new DynamicTableEntity(); ent.RowKey = string.Format("{0}-{1}", DateTime.Now.Add(taskUpdate.Result.NextRunDelay).ToUniversalTime().ToString("yyyyMMddHHmmssffff"), taskUpdate.Task.Id); ent["Data"] = new EntityProperty(taskUpdate.Result.Data ?? taskUpdate.Task.Data); Exception ex = taskUpdate.Result.Exception; int retyCount = taskUpdate.Result.ResultState == ScheduledTaskResultState.Failed ? taskUpdate.Task.FailedTimes + 1 : taskUpdate.Task.FailedTimes; if (retyCount > 0) ent["RetryCount"] = new EntityProperty(retyCount); if (ex != null) ent["LastError"] = new EntityProperty(Json.Encode(new { Message = ex.Message, StackTrace = ex.StackTrace, InnerException = ex.InnerException == null ? "" : ex.InnerException.Message })); ent["Id"] = new EntityProperty(taskUpdate.Task.Id); ent.PartitionKey = taskUpdate.Task.Channel; switch (taskUpdate.Result.ResultState) { case ScheduledTaskResultState.Redirect: ent.PartitionKey = taskUpdate.Result.NewChannel; break; case ScheduledTaskResultState.Unhandled: ent.PartitionKey = ent.PartitionKey + "-unhandled"; break; case ScheduledTaskResultState.Failed: ent.RowKey = taskUpdate.Task.temporaryTask.RowKey; break; } return ent; }