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);
        }
Example #5
0
        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" );
        }
Example #6
0
        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" );
        }
Example #7
0
        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);
 }
Example #11
0
        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 };
            }
        }
Example #15
0
 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);
        }
Example #18
0
        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);
        }
Example #20
0
    //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;
      }
    }
Example #21
0
 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);
     }
 }
Example #23
0
        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);
        }
Example #25
0
        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
                      };
            }
        }
Example #26
0
 internal static void WriteString(IDictionary<string, EntityProperty> prop, string key, string val)
 {
     Debug.Assert(!prop.ContainsKey(key));
     prop[key] = new EntityProperty(val);
 }
Example #27
0
        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;
        }