public async Task <IEnumerable <T> > ConvertAsync(DocumentDBAttribute attribute, CancellationToken cancellationToken)
        {
            DocumentDBContext context = _config.CreateContext(attribute);

            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName);

            List <T> finalResults = new List <T>();

            string continuation = null;

            SqlQuerySpec sqlSpec = new SqlQuerySpec
            {
                QueryText  = context.ResolvedAttribute.SqlQuery,
                Parameters = context.ResolvedAttribute.SqlQueryParameters ?? new SqlParameterCollection()
            };

            do
            {
                DocumentQueryResponse <T> response = await DocumentDBUtility.RetryAsync(
                    () => context.Service.ExecuteNextAsync <T>(collectionUri, sqlSpec, continuation),
                    context.MaxThrottleRetries);

                finalResults.AddRange(response.Results);
                continuation = response.ResponseContinuation;
            }while (!string.IsNullOrEmpty(continuation));

            return(finalResults);
        }
        internal object BindForOutput(DocumentDBAttribute attribute, Type parameterType, TraceWriter trace)
        {
            DocumentDBContext context = CreateContext(attribute, trace);

            Type collectorType = typeof(DocumentDBAsyncCollector <>).MakeGenericType(parameterType);

            return(Activator.CreateInstance(collectorType, context));
        }
Example #3
0
        internal static async Task CreateIfNotExistAsync(DocumentDBContext context)
        {
            await DocumentDBUtility.RetryAsync(() => CreateDatabaseIfNotExistsAsync(context.Service, context.ResolvedAttribute.DatabaseName),
                                               context.MaxThrottleRetries, codesToIgnore : HttpStatusCode.Conflict);

            await DocumentDBUtility.RetryAsync(() => CreateDocumentCollectionIfNotExistsAsync(context.Service, context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName, context.ResolvedAttribute.PartitionKey, context.ResolvedAttribute.CollectionThroughput),
                                               context.MaxThrottleRetries, codesToIgnore : HttpStatusCode.Conflict);
        }
        internal Task <IValueBinder> BindForItemAsync(DocumentDBAttribute attribute, Type type, TraceWriter trace)
        {
            DocumentDBContext context = CreateContext(attribute, trace);

            Type         genericType = typeof(DocumentDBItemValueBinder <>).MakeGenericType(type);
            IValueBinder binder      = (IValueBinder)Activator.CreateInstance(genericType, context);

            return(Task.FromResult(binder));
        }
        public async Task <IBinding> TryCreateAsync(BindingProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            ParameterInfo       parameter = context.Parameter;
            DocumentDBAttribute attribute = parameter.GetCustomAttribute <DocumentDBAttribute>(inherit: false);

            if (attribute == null)
            {
                return(null);
            }

            if (string.IsNullOrEmpty(_docDBConfig.ConnectionString) &&
                string.IsNullOrEmpty(attribute.ConnectionString))
            {
                throw new InvalidOperationException(
                          string.Format(CultureInfo.CurrentCulture,
                                        "The DocumentDB connection string must be set either via a '{0}' app setting, via the DocumentDBAttribute.ConnectionString property or via DocumentDBConfiguration.ConnectionString.",
                                        DocumentDBConfiguration.AzureWebJobsDocumentDBConnectionStringName));
            }

            DocumentDBContext documentDBContext = CreateContext(_docDBConfig, attribute, _jobHostConfig.NameResolver);

            if (attribute.CreateIfNotExists)
            {
                await CreateIfNotExistAsync(documentDBContext.Service, documentDBContext.ResolvedDatabaseName, documentDBContext.ResolvedCollectionName);
            }

            Type coreType = TypeUtility.GetCoreType(parameter.ParameterType);

            IBinding binding = null;

            try
            {
                binding = BindingFactory.BindGenericCollector(parameter, typeof(DocumentDBAsyncCollector <>), coreType,
                                                              _jobHostConfig.GetService <IConverterManager>(), (s) => documentDBContext);
            }
            catch (Exception ex)
            {
                // BindingFactory uses a couple levels of reflection so we get TargetInvocationExceptions here.
                // This pulls out the root exception and rethrows it.
                while (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                ExceptionDispatchInfo.Capture(ex).Throw();
            }

            return(binding);
        }
Example #6
0
        internal Task <IValueBinder> BindForItemAsync(DocumentDBAttribute attribute, Type type)
        {
            if (string.IsNullOrEmpty(attribute.Id))
            {
                throw new InvalidOperationException("The 'Id' property of a DocumentDB single-item input binding cannot be null or empty.");
            }

            DocumentDBContext context = CreateContext(attribute);

            Type         genericType = typeof(DocumentDBItemValueBinder <>).MakeGenericType(type);
            IValueBinder binder      = (IValueBinder)Activator.CreateInstance(genericType, context);

            return(Task.FromResult(binder));
        }
Example #7
0
        internal static async Task UpsertDocument(DocumentDBContext context, T item)
        {
            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName);

            // DocumentClient does not accept strings directly.
            object convertedItem = item;

            if (item is string)
            {
                convertedItem = JObject.Parse(item.ToString());
            }

            await DocumentDBUtility.RetryAsync(() => context.Service.UpsertDocumentAsync(collectionUri, convertedItem), context.MaxThrottleRetries);
        }
Example #8
0
        internal static async Task SetValueInternalAsync(JObject originalItem, T newItem, DocumentDBContext context)
        {
            JObject currentValue = JObject.FromObject(newItem);

            if (HasChanged(originalItem, currentValue))
            {
                // make sure it's not the id that has changed
                string originalId = null;
                string currentId  = null;
                if (TryGetId(currentValue, out currentId) &&
                    !string.IsNullOrEmpty(currentId) &&
                    TryGetId(originalItem, out originalId) &&
                    !string.IsNullOrEmpty(originalId))
                {
                    // make sure it's not the Id that has changed
                    if (!string.Equals(originalId, currentId, StringComparison.Ordinal))
                    {
                        throw new InvalidOperationException("Cannot update the 'Id' property.");
                    }
                }
                else
                {
                    // If the serialzied object does not have a lowercase 'id' property, DocDB will reject it.
                    // We'll just short-circuit here since we validate that the 'id' hasn't changed.
                    throw new InvalidOperationException(string.Format("The document must have an 'id' property."));
                }

                Uri documentUri = UriFactory.CreateDocumentUri(context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName, originalId);
                await DocumentDBUtility.RetryAsync(() => context.Service.ReplaceDocumentAsync(documentUri, newItem),
                                                   context.MaxThrottleRetries);
            }
        }
Example #9
0
 public DocumentDBItemValueBinder(DocumentDBContext context)
 {
     _context = context;
 }
Example #10
0
 public DocumentDBAsyncCollector(DocumentDBContext docDBContext)
 {
     _docDBContext = docDBContext;
 }
Example #11
0
 internal static async Task UpsertDocument(DocumentDBContext context, T item)
 {
     Uri collectionUri = UriFactory.CreateDocumentCollectionUri(context.ResolvedAttribute.DatabaseName, context.ResolvedAttribute.CollectionName);
     await DocumentDBUtility.RetryAsync(() => context.Service.UpsertDocumentAsync(collectionUri, item), context.MaxThrottleRetries);
 }