Ejemplo n.º 1
0
        private static EdmModel BuildEdmModel(Schema schema, PartitionResolver partitionResolver)
        {
            var model = new EdmModel();

            var container = new EdmEntityContainer("Squidex", "Container");

            var schemaType = schema.BuildEdmType(partitionResolver, x =>
            {
                model.AddElement(x);

                return(x);
            });

            var entityType = new EdmEntityType("Squidex", schema.Name);

            entityType.AddStructuralProperty("data", new EdmComplexTypeReference(schemaType, false));
            entityType.AddStructuralProperty("version", EdmPrimitiveTypeKind.Int32);
            entityType.AddStructuralProperty("created", EdmPrimitiveTypeKind.DateTimeOffset);
            entityType.AddStructuralProperty("createdBy", EdmPrimitiveTypeKind.String);
            entityType.AddStructuralProperty("lastModified", EdmPrimitiveTypeKind.DateTimeOffset);
            entityType.AddStructuralProperty("lastModifiedBy", EdmPrimitiveTypeKind.String);

            model.AddElement(container);
            model.AddElement(schemaType);
            model.AddElement(entityType);

            container.AddEntitySet("ContentSet", entityType);

            return(model);
        }
        private void AddData(Schema schema, PartitionResolver partitionResolver)
        {
            foreach (var field in schema.Fields.Where(x => x.IsForApi(true)))
            {
                var description = $"The values of the '{field.DisplayName()}' field.";

                AddObject(field.Name, $"The values of the '{field.DisplayName()}' field.", () =>
                {
                    foreach (var partition in partitionResolver(field.Partitioning).AllKeys)
                    {
                        var description = $"The '{partition}' value of the '{field.DisplayName()}' field.";

                        if (field is ArrayField arrayField)
                        {
                            AddObject(partition, description, () =>
                            {
                                foreach (var nestedField in arrayField.Fields.Where(x => x.IsForApi(true)))
                                {
                                    var description = $"The value of the '{nestedField.DisplayName()}' nested field.";

                                    AddAny(field.Name, description);
                                }
                            });
                        }
                        else
                        {
                            AddAny(partition, description);
                        }
                    }
                });
            }
        }
Ejemplo n.º 3
0
        public static JsonSchema4 BuildJsonSchema(this Schema schema, PartitionResolver partitionResolver, Func <string, JsonSchema4, JsonSchema4> schemaResolver)
        {
            Guard.NotNull(schemaResolver, nameof(schemaResolver));
            Guard.NotNull(partitionResolver, nameof(partitionResolver));

            var schemaName = schema.Name.ToPascalCase();

            var jsonTypeVisitor = new JsonTypeVisitor(schemaResolver);
            var jsonSchema      = new JsonSchema4 {
                Type = JsonObjectType.Object
            };

            foreach (var field in schema.Fields.Where(x => !x.IsHidden))
            {
                var partitionProperty = CreateProperty(field);
                var partitionObject   = new JsonSchema4 {
                    Type = JsonObjectType.Object, AllowAdditionalProperties = false
                };
                var partition = partitionResolver(field.Partitioning);

                foreach (var partitionItem in partition)
                {
                    var partitionItemProperty = field.Visit(jsonTypeVisitor);

                    partitionItemProperty.Description = partitionItem.Name;
                    partitionObject.Properties.Add(partitionItem.Key, partitionItemProperty);
                }

                partitionProperty.Reference = schemaResolver($"{schemaName}{field.Name.ToPascalCase()}Property", partitionObject);

                jsonSchema.Properties.Add(field.Name, partitionProperty);
            }

            return(jsonSchema);
        }
Ejemplo n.º 4
0
        public void AddToJsonSchema(JsonSchema4 schema, PartitionResolver partitionResolver, string schemaName, Func <string, JsonSchema4, JsonSchema4> schemaResolver)
        {
            Guard.NotNull(schema, nameof(schema));
            Guard.NotNull(schemaResolver, nameof(schemaResolver));
            Guard.NotNull(partitionResolver, nameof(partitionResolver));

            var partitionProperty = CreateProperty();
            var partitionObject   = new JsonSchema4 {
                Type = JsonObjectType.Object, AllowAdditionalProperties = false
            };
            var partition = partitionResolver(partitioning);

            foreach (var partitionItem in partition)
            {
                var partitionItemProperty = new JsonProperty {
                    Description = partitionItem.Name, IsRequired = RawProperties.IsRequired
                };

                PrepareJsonSchema(partitionItemProperty, schemaResolver);

                partitionObject.Properties.Add(partitionItem.Key, partitionItemProperty);
            }

            partitionProperty.Reference = schemaResolver($"{schemaName}{Name.ToPascalCase()}Property", partitionObject);

            schema.Properties.Add(Name, partitionProperty);
        }
Ejemplo n.º 5
0
        public static EdmComplexType BuildEdmType(this Schema schema, PartitionResolver partitionResolver, Func <EdmComplexType, EdmComplexType> typeResolver)
        {
            Guard.NotNull(typeResolver, nameof(typeResolver));
            Guard.NotNull(partitionResolver, nameof(partitionResolver));

            var schemaName = schema.Name.ToPascalCase();

            var edmType = new EdmComplexType("Squidex", schemaName);

            foreach (var field in schema.FieldsByName.Values.Where(x => !x.IsHidden))
            {
                var edmValueType = EdmTypeVisitor.CreateEdmType(field);

                if (edmValueType == null)
                {
                    continue;
                }

                var partitionType = typeResolver(new EdmComplexType("Squidex", $"{schemaName}{field.Name.ToPascalCase()}Property"));
                var partition     = partitionResolver(field.Partitioning);

                foreach (var partitionItem in partition)
                {
                    partitionType.AddStructuralProperty(partitionItem.Key, edmValueType);
                }

                edmType.AddStructuralProperty(field.Name.EscapeEdmField(), new EdmComplexTypeReference(partitionType, false));
            }

            return(edmType);
        }
Ejemplo n.º 6
0
        public GraphQLModel(IAppEntity app,
                            IEnumerable <ISchemaEntity> schemas,
                            int pageSizeContents,
                            int pageSizeAssets,
                            IUrlGenerator urlGenerator, ISemanticLog log)
        {
            this.log = log;

            partitionResolver = app.PartitionResolver();

            CanGenerateAssetSourceUrl = urlGenerator.CanGenerateAssetSourceUrl;

            assetType     = new AssetGraphType(this);
            assetListType = new ListGraphType(new NonNullGraphType(assetType));

            graphQLTypeVisitor = new GraphQLTypeVisitor(contentTypes, this, assetListType);

            var allSchemas = schemas.Where(x => x.SchemaDef.IsPublished).ToList();

            BuildSchemas(allSchemas);

            graphQLSchema = BuildSchema(this, pageSizeContents, pageSizeAssets, allSchemas);
            graphQLSchema.RegisterValueConverter(JsonConverter.Instance);
            graphQLSchema.RegisterValueConverter(InstantConverter.Instance);

            InitializeContentTypes(allSchemas, pageSizeContents);
        }
Ejemplo n.º 7
0
        public Builder(IAppEntity app)
        {
            partitionResolver = app.PartitionResolver();

            fieldVisitor      = new FieldVisitor(this);
            fieldInputVisitor = new FieldInputVisitor(this);
        }
Ejemplo n.º 8
0
        public static JsonSchema BuildJsonSchemaFlat(this Schema schema, PartitionResolver partitionResolver,
                                                     ResolvedComponents components,
                                                     JsonTypeFactory?factory = null,
                                                     bool withHidden         = false,
                                                     bool withComponents     = false)
        {
            Guard.NotNull(partitionResolver);
            Guard.NotNull(components);

            factory ??= DefaultFactory;

            var jsonSchema = JsonTypeBuilder.Object();

            foreach (var field in schema.Fields.ForApi(withHidden))
            {
                var property =
                    JsonTypeVisitor.BuildProperty(
                        field, components, schema,
                        factory,
                        withHidden,
                        withComponents);

                // Property is null for UI fields.
                if (property != null)
                {
                    property.SetRequired(false);
                    property.SetDescription(field);

                    jsonSchema.Properties.Add(field.Name, property);
                }
            }

            return(jsonSchema);
        }
Ejemplo n.º 9
0
        public static JsonSchema BuildJsonSchema(this Schema schema, PartitionResolver partitionResolver,
                                                 ResolvedComponents components,
                                                 JsonTypeFactory?factory = null,
                                                 bool withHidden         = false,
                                                 bool withComponents     = false)
        {
            Guard.NotNull(partitionResolver);
            Guard.NotNull(components);

            factory ??= DefaultFactory;

            var jsonSchema = JsonTypeBuilder.Object();

            foreach (var field in schema.Fields.ForApi(withHidden))
            {
                var typeName = $"{schema.TypeName()}{field.Name.ToPascalCase()}PropertyDto";

                // Create a reference to give it a nice name in code generation.
                var(reference, actual) = factory(typeName);

                if (actual != null)
                {
                    var partitioning = partitionResolver(field.Partitioning);

                    foreach (var partitionKey in partitioning.AllKeys)
                    {
                        var property =
                            JsonTypeVisitor.BuildProperty(
                                field, components, schema,
                                factory,
                                withHidden,
                                withComponents);

                        // Property is null for UI fields.
                        if (property != null)
                        {
                            var isOptional = partitioning.IsOptional(partitionKey);

                            var name = partitioning.GetName(partitionKey);

                            // Required if property is required and language/partitioning is not optional.
                            property.SetRequired(field.RawProperties.IsRequired && !isOptional);
                            property.SetDescription(name);

                            actual.Properties.Add(partitionKey, property);
                        }
                    }
                }

                var propertyReference =
                    JsonTypeBuilder.ReferenceProperty(reference)
                    .SetDescription(field)
                    .SetRequired(field.RawProperties.IsRequired);

                jsonSchema.Properties.Add(field.Name, propertyReference);
            }

            return(jsonSchema);
        }
Ejemplo n.º 10
0
        public static ContentData Enrich(this ContentData data, Schema schema, PartitionResolver partitionResolver)
        {
            var enricher = new ContentEnricher(schema, partitionResolver);

            enricher.Enrich(data);

            return(data);
        }
Ejemplo n.º 11
0
        public ContentValidator(Schema schema, PartitionResolver partitionResolver, ValidationContext context)
        {
            Guard.NotNull(schema, nameof(schema));
            Guard.NotNull(partitionResolver, nameof(partitionResolver));

            this.schema            = schema;
            this.context           = context;
            this.partitionResolver = partitionResolver;
        }
Ejemplo n.º 12
0
        public Builder(IAppEntity app, SharedTypes sharedTypes)
        {
            this.sharedTypes = sharedTypes;

            partitionResolver = app.PartitionResolver();

            fieldVisitor      = new FieldVisitor(this);
            fieldInputVisitor = new FieldInputVisitor(this);
        }
Ejemplo n.º 13
0
        public ContentEnricher(Schema schema, PartitionResolver partitionResolver)
        {
            Guard.NotNull(schema, nameof(schema));
            Guard.NotNull(partitionResolver, nameof(partitionResolver));

            this.schema = schema;

            this.partitionResolver = partitionResolver;
        }
Ejemplo n.º 14
0
        public DefaultValueGenerator(Schema schema, PartitionResolver partitionResolver)
        {
            Guard.NotNull(schema, nameof(schema));
            Guard.NotNull(partitionResolver, nameof(partitionResolver));

            this.schema = schema;

            this.partitionResolver = partitionResolver;
        }
Ejemplo n.º 15
0
        public ContentValidator(PartitionResolver partitionResolver, ValidationContext context, IEnumerable <IValidatorsFactory> factories)
        {
            Guard.NotNull(context, nameof(context));
            Guard.NotNull(factories, nameof(factories));
            Guard.NotNull(partitionResolver, nameof(partitionResolver));

            this.context           = context;
            this.factories         = factories;
            this.partitionResolver = partitionResolver;
        }
Ejemplo n.º 16
0
        public async Task RoundRobinDistributesFairlyWhenCalledConcurrently(string[] partitions)
        {
            var concurrentCount         = 4;
            var assignmentsPerPartition = 20;
            var iterationCount          = partitions.Length * assignmentsPerPartition;
            var resolver    = new PartitionResolver();
            var assigned    = new List <string>();
            var activeTasks = new List <Task>();

            // Create a function that assigns partitions in a loop and track them.

            Task roundRobin()
            {
                for (var index = 0; index < iterationCount; index++)
                {
                    assigned.Add(resolver.AssignRoundRobin(partitions));
                }

                return(Task.CompletedTask);
            }

            // Run assignment concurrently.

            for (var concurrentIndex = 0; concurrentIndex < concurrentCount; ++concurrentIndex)
            {
                activeTasks.Add(roundRobin());
            }

            await Task.WhenAll(activeTasks);

            // When grouped, the count of each partition should equal the iteration count for each
            // concurrent invocation.

            var partitionAssignments = assigned
                                       .GroupBy(item => item)
                                       .Select(group => new { Key = group.Key, Count = group.Count() });

            var assignmentHash          = new HashSet <string>();
            var expectedAssignmentCount = (concurrentCount * assignmentsPerPartition);

            // Verify that each assignment is for a valid partition and has the expected distribution.

            foreach (var partitionAssignment in partitionAssignments)
            {
                Assert.That(partitionAssignment.Count, Is.EqualTo(expectedAssignmentCount), $"The count for key: [{ partitionAssignment.Key}] should match the total number of iterations.");
                assignmentHash.Add(partitionAssignment.Key);
            }

            // Verify that all partitions were assigned.

            foreach (var partition in partitions)
            {
                Assert.That(assignmentHash.Contains(partition), Is.True, $"Partition: [{ partition }] should have had assignments.");
            }
        }
Ejemplo n.º 17
0
        public void PartitionResolverResolvePartitionTest()
        {
            PartitionResolver     pr      = new PartitionResolver();
            AspSessionPersistence persist = new AspSessionPersistence();
            string cnx_str    = pr.ResolvePartition(persist.GenerateSessionId());
            bool   isAssertOk = cnx_str.Contains("Initial Catalog=");

            Assert.AreEqual(isAssertOk, true);
            isAssertOk = cnx_str.Contains("Data Source=");
            Assert.AreEqual(isAssertOk, true);
        }
Ejemplo n.º 18
0
        public static async Task ValidateAsync(this ContentData data, Schema schema, PartitionResolver partitionResolver, IList <ValidationError> errors)
        {
            var validator = new ContentValidator(schema, partitionResolver);

            await validator.ValidateAsync(data);

            foreach (var error in validator.Errors)
            {
                errors.Add(error);
            }
        }
Ejemplo n.º 19
0
        public void DeleteSessionTest()
        {
            PartitionResolver     pr      = new PartitionResolver();
            AspSessionPersistence persist = new AspSessionPersistence();
            var sessionid = persist.GenerateSessionId();

            persist.DeleteSession(sessionid);
            var sessionSaved = persist.LoadSession(sessionid);

            Assert.IsNull(sessionSaved, null);
        }
Ejemplo n.º 20
0
        public static FilterSchema BuildDataSchema(this Schema schema, PartitionResolver partitionResolver,
                                                   ResolvedComponents components)
        {
            Guard.NotNull(partitionResolver);
            Guard.NotNull(components);

            var fields = new List <FilterField>();

            var schemaName = schema.DisplayName();

            foreach (var field in schema.Fields.ForApi(true))
            {
                var fieldSchema = FilterVisitor.BuildProperty(field, components);

                if (fieldSchema == null)
                {
                    continue;
                }

                var partitioning    = partitionResolver(field.Partitioning);
                var partitionFields = new List <FilterField>();

                foreach (var partitionKey in partitioning.AllKeys)
                {
                    var partitionDescription = FieldPartitionDescription(field, partitioning.GetName(partitionKey) ?? partitionKey);

                    var partitionField = new FilterField(
                        fieldSchema,
                        partitionKey,
                        partitionDescription,
                        true);

                    partitionFields.Add(partitionField);
                }

                var filterable = new FilterField(
                    new FilterSchema(FilterSchemaType.Object)
                {
                    Fields = partitionFields.ToReadonlyList()
                },
                    field.Name,
                    FieldDescription(schemaName, field));

                fields.Add(filterable);
            }

            var dataSchema = new FilterSchema(FilterSchemaType.Object)
            {
                Fields = fields.ToReadonlyList()
            };

            return(dataSchema);
        }
Ejemplo n.º 21
0
        public void PartitionKeyAssignmentIsStable(string[] partitions)
        {
            var iterationCount = 25;
            var key            = "this-is-a-key-1";
            var resolver       = new PartitionResolver();
            var expected       = resolver.AssignForPartitionKey(key, partitions);

            for (var index = 0; index < iterationCount; ++index)
            {
                Assert.That(resolver.AssignForPartitionKey(key, partitions), Is.EqualTo(expected), $"The assignment for iteration: [{ index }] was unstable.");
            }
        }
Ejemplo n.º 22
0
        public void RoundRobinDistributesFairly(string[] partitions)
        {
            var resolver = new PartitionResolver();

            for (var index = 0; index < 100; index++)
            {
                var expected = partitions[index % partitions.Length];
                var assigned = resolver.AssignRoundRobin(partitions);

                Assert.That(assigned, Is.EqualTo(expected), $"The assignment was unexpected for index: [{ index }].");
            }
        }
Ejemplo n.º 23
0
        internal Builder(IAppEntity app,
                         OpenApiDocument document,
                         OpenApiSchemaResolver schemaResolver,
                         OpenApiSchemaGenerator schemaGenerator)
        {
            this.partitionResolver = app.PartitionResolver();

            Document = document;

            AppName = app.Name;

            ChangeStatusSchema = schemaGenerator.GenerateWithReference <JsonSchema>(typeof(ChangeStatusDto).ToContextualType(), schemaResolver);
        }
        public async Task <IEnumerable <ShortEntityId> > QueryObservablesAsync(GatewayRequest request)
        {
            try
            {
                // Validates parameter
                if (string.IsNullOrWhiteSpace(request?.Topic))
                {
                    throw new ArgumentException($"Parameter {nameof(request)} is null or invalid.", nameof(request));
                }

                // Gets service proxy
                IRegistryService proxy = GetServiceProxy(
                    PartitionResolver.Resolve(request.Topic, OwinCommunicationListener.RegistryServicePartitionCount),
                    OwinCommunicationListener.RegistryServiceUri);
                if (proxy == null)
                {
                    throw new ApplicationException("The ServiceProxy cannot be null.");
                }

                // Invokes actor using proxy
                ServiceEventSource.Current.Message($"Retrieving observables...\r\n[Publication]: Topic=[{request.Topic}]");
                IEnumerable <EntityId> entityIds = await proxy.QueryObservablesAsync(
                    request.Topic,
                    (request.FilterExpressions != null) && request.FilterExpressions.Any()
                    ?request.FilterExpressions.First()
                        : null);

                if ((entityIds == null) || !entityIds.Any())
                {
                    return(null);
                }
                return(entityIds.Select(e => new ShortEntityId(e)));
            }
            catch (AggregateException ex)
            {
                if (!(ex.InnerExceptions?.Count > 0))
                {
                    throw new HttpResponseException(this.Request.CreateErrorResponse(HttpStatusCode.NotFound, ex.Message));
                }
                foreach (Exception exception in ex.InnerExceptions)
                {
                    ServiceEventSource.Current.Message(exception.Message);
                }
                throw new HttpResponseException(this.Request.CreateErrorResponse(HttpStatusCode.NotFound, ex.Message));
            }
            catch (Exception ex)
            {
                ServiceEventSource.Current.Message(ex.Message);
                throw new HttpResponseException(this.Request.CreateErrorResponse(HttpStatusCode.NotFound, ex.Message));
            }
        }
Ejemplo n.º 25
0
        public static async Task ValidateAsync(this NamedContentData data, PartitionResolver partitionResolver, IList <ValidationError> errors,
                                               Schema?schema = null, ValidationMode mode = ValidationMode.Default, Func <ValidationContext, ValidationContext>?updater = null)
        {
            var context = CreateContext(schema, mode, updater);

            var validator = new ContentValidator(partitionResolver, context, Enumerable.Repeat(Factory, 1));

            await validator.ValidateInputAsync(data);

            foreach (var error in validator.Errors)
            {
                errors.Add(error);
            }
        }
Ejemplo n.º 26
0
        public void RefreshSessionTest()
        {
            PartitionResolver     pr      = new PartitionResolver();
            AspSessionPersistence persist = new AspSessionPersistence();
            AspSessionContents    st      = new AspSessionContents();

            this.CreateSessionState(st);
            var sessionid = persist.GenerateSessionId();

            persist.SaveSession(sessionid, st, 20);
            persist.RefreshSession(sessionid);
            var sessionSaved = persist.LoadSession(sessionid);

            Assert.IsNotNull(sessionSaved);
        }
Ejemplo n.º 27
0
        public GraphQLModel(IAppEntity app, IEnumerable <ISchemaEntity> schemas, IGraphQLUrlGenerator urlGenerator)
        {
            this.app = app;

            partitionResolver = app.PartitionResolver();

            CanGenerateAssetSourceUrl = urlGenerator.CanGenerateAssetSourceUrl;

            assetType   = new AssetGraphType(this);
            schemasById = schemas.ToDictionary(x => x.Id);
            schemaTypes = new QueryGraphTypeVisitor(GetContentType, new ListGraphType(new NonNullGraphType(assetType)));

            graphQLSchema = BuildSchema(this);

            InitializeContentTypes();
        }
Ejemplo n.º 28
0
        public EdmComplexType BuildEdmType(PartitionResolver partitionResolver, Func <EdmComplexType, EdmComplexType> typeResolver)
        {
            Guard.NotNull(typeResolver, nameof(typeResolver));
            Guard.NotNull(partitionResolver, nameof(partitionResolver));

            var schemaName = Name.ToPascalCase();

            var edmType = new EdmComplexType("Squidex", schemaName);

            foreach (var field in fieldsByName.Values.Where(x => !x.IsHidden))
            {
                field.AddToEdmType(edmType, partitionResolver, schemaName, typeResolver);
            }

            return(edmType);
        }
Ejemplo n.º 29
0
        public OperationsBuilder Schema(Schema schema, PartitionResolver partitionResolver, ResolvedComponents components, bool flat)
        {
            var typeName = schema.TypeName();

            var dataSchema = RegisterReference($"{typeName}DataDto", _ =>
            {
                return(schema.BuildJsonSchemaDynamic(partitionResolver, components, CreateReference, false, true));
            });

            var contentDataSchema = dataSchema;

            if (flat)
            {
                contentDataSchema = RegisterReference($"{typeName}FlatDataDto", _ =>
                {
                    return(schema.BuildJsonSchemaFlat(partitionResolver, components, CreateReference, false, true));
                });
            }

            var contentSchema = RegisterReference($"{typeName}ContentDto", _ =>
            {
                return(ContentJsonSchema.Build(contentDataSchema, true));
            });

            var contentsSchema = RegisterReference($"{typeName}ContentResultDto", _ =>
            {
                return(BuildResult(contentSchema));
            });

            var path = $"api/content/{AppName}/{schema.Name}";

            var builder = new OperationsBuilder
            {
                ContentSchema     = contentSchema,
                ContentsSchema    = contentsSchema,
                DataSchema        = dataSchema,
                Path              = path,
                Parent            = this,
                SchemaDisplayName = schema.DisplayName(),
                SchemaName        = schema.Name,
                SchemaTypeName    = typeName
            };

            builder.AddTag("API endpoints for [schema] content items.");

            return(builder);
        }
Ejemplo n.º 30
0
        public void SaveSessionTest()
        {
            PartitionResolver     pr      = new PartitionResolver();
            AspSessionPersistence persist = new AspSessionPersistence();
            AspSessionContents    st      = new AspSessionContents();

            this.CreateSessionState(st);
            var sessionid = persist.GenerateSessionId();

            persist.SaveSession(sessionid, st, 20);
            var sessionSaved = persist.LoadSession(sessionid);

            foreach (var item in sessionSaved)
            {
                Assert.AreEqual(item.Value, st[item.Key]);
            }
        }