Ejemplo n.º 1
0
        /// <summary>
        /// Create a relationship linking by creating an entity attribute definition instance with a trait.
        /// This allows you to add a resolution guidance to customize your data.
        /// </summary>
        /// <param name="cdmCorpus"> The CDM corpus. </param>
        /// <param name="associatedEntityName"> The name of the associated entity. </param>
        /// <param name="foreignKeyName"> The name of the foreign key. </param>
        /// <param name="attributeExplanation"> The explanation of the attribute.</param>
        /// <returns> The instance of entity attribute definition. </returns>
        private static CdmEntityAttributeDefinition CreateEntityAttributeForRelationshipBetweenTwoEntities(
            CdmCorpusDefinition cdmCorpus,
            string associatedEntityName,
            string foreignKeyName,
            string attributeExplanation)
        {
            // Define a relationship by creating an entity attribute
            var entityAttributeDef = cdmCorpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, foreignKeyName);

            entityAttributeDef.Explanation = attributeExplanation;
            // Creating an entity reference for the associated entity
            CdmEntityReference associatedEntityRef = cdmCorpus.MakeRef <CdmEntityReference>(CdmObjectType.EntityRef, associatedEntityName, false);

            // Creating a "is.identifiedBy" trait for entity reference
            CdmTraitReference traitReference = cdmCorpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, "is.identifiedBy", false);

            traitReference.Arguments.Add(null, $"{associatedEntityName}/(resolvedAttributes)/{associatedEntityName}Id");

            // Add the trait to the attribute's entity reference
            associatedEntityRef.AppliedTraits.Add(traitReference);
            entityAttributeDef.Entity  = associatedEntityRef;
            entityAttributeDef.Purpose = CreateRelationshipMeanings(cdmCorpus, "Non-simple resolution guidance sample");

            // Add resolution guidance
            var attributeResolution = cdmCorpus.MakeObject <CdmAttributeResolutionGuidance>(CdmObjectType.AttributeResolutionGuidanceDef);

            attributeResolution.entityByReference = attributeResolution.makeEntityByReference();
            attributeResolution.entityByReference.allowReference = true;
            attributeResolution.renameFormat = "{m}";
            var entityAttribute = CreateTypeAttributeWithPurposeAndDataType(cdmCorpus, $"{foreignKeyName}Id", "identifiedBy", "entityId");

            attributeResolution.entityByReference.foreignKeyAttribute = entityAttribute as CdmTypeAttributeDefinition;
            entityAttributeDef.ResolutionGuidance = attributeResolution;

            return(entityAttributeDef);
        }
Ejemplo n.º 2
0
        public async Task TestNestedProjUsingObjectModel()
        {
            CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, "TestNestedProjUsingObjectModel");

            corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestNestedProjUsingObjectModel")));
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            // Create an ExcludeAttributes operation
            CdmOperationExcludeAttributes excludeAttrsOp = corpus.MakeObject <CdmOperationExcludeAttributes>(CdmObjectType.OperationExcludeAttributesDef);

            excludeAttrsOp.ExcludeAttributes.Add("id");
            excludeAttrsOp.ExcludeAttributes.Add("date");
            projection.Operations.Add(excludeAttrsOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create another projection that uses the previous projection as its source
            CdmProjection projection2 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            projection2.Source = projectionEntityRef;

            // Create an ExcludeAttributes operation
            CdmOperationExcludeAttributes excludeAttrsOp2 = corpus.MakeObject <CdmOperationExcludeAttributes>(CdmObjectType.OperationExcludeAttributesDef);

            excludeAttrsOp2.ExcludeAttributes.Add("value");
            projection2.Operations.Add(excludeAttrsOp2);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef2 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef2.ExplicitReference = projection2;

            // Create an entity attribute that contains this projection and add this to the entity
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef2;
            entity.Attributes.Add(entityAttribute);

            // Resolve the entity
            CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot);

            // Verify correctness of the resolved attributes after running the ExcludeAttributes operations
            // Original set of attributes: ["id", "name", "value", "date"]
            // Excluded attributes: ["id", "date"], ["value"]
            Assert.AreEqual(1, resolvedEntity.Attributes.Count);
            Assert.AreEqual("name", (resolvedEntity.Attributes[0] as CdmTypeAttributeDefinition).Name);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Create a relationship linking with an attribute an entity attribute definition instance without a trait.
        /// </summary>
        /// <param name="cdmCorpus"> The CDM corpus. </param>
        /// <param name="associatedEntityName"> The name of . </param>
        /// <param name="foreignKeyName"> The name of the foreign key. </param>
        /// <param name="attributeExplanation"> The explanation of the attribute.</param>
        /// <returns> The instance of entity attribute definition. </returns>
        private static CdmEntityAttributeDefinition CreateSimpleEntityAttributeForRelationshipBetweenTwoEntities(
            CdmCorpusDefinition cdmCorpus,
            string associatedEntityName,
            string foreignKeyName,
            string attributeExplanation)
        {
            // Define a relationship by creating an entity attribute
            var entityAttributeDef = cdmCorpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, foreignKeyName);

            entityAttributeDef.Explanation = attributeExplanation;

            // Creating an entity reference for the associated entity - simple name reference
            entityAttributeDef.Entity  = cdmCorpus.MakeRef <CdmEntityReference>(CdmObjectType.EntityRef, associatedEntityName, true);
            entityAttributeDef.Purpose = CreateRelationshipMeanings(cdmCorpus, "Simple resolution guidance sample");

            // Add resolution guidance - enable reference
            var attributeResolution = cdmCorpus.MakeObject <CdmAttributeResolutionGuidance>(CdmObjectType.AttributeResolutionGuidanceDef);

            attributeResolution.entityByReference = attributeResolution.makeEntityByReference();
            attributeResolution.entityByReference.allowReference = true;
            entityAttributeDef.ResolutionGuidance = attributeResolution;

            return(entityAttributeDef);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Create an entity 'TestEntityNestedProjection' that extends from a projection
        /// </summary>
        /// <param name="corpus"></param>
        /// <param name="manifestDefault"></param>
        /// <param name="localRoot"></param>
        /// <returns></returns>
        private CdmEntityDefinition CreateEntityTestEntityNestedProjection(CdmCorpusDefinition corpus, CdmManifestDefinition manifestDefault, CdmFolderDefinition localRoot)
        {
            string entityName = "TestEntityNestedProjection";

            CdmEntityReference inlineProjectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            inlineProjectionEntityRef.ExplicitReference = CreateNestedProjection(corpus);


            CdmEntityDefinition entityTestEntityNestedProjection = corpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, entityName);

            entityTestEntityNestedProjection.ExtendsEntity = inlineProjectionEntityRef;

            CdmDocumentDefinition entityTestEntityNestedProjectionDoc = corpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{entityName}.cdm.json", false);

            entityTestEntityNestedProjectionDoc.Imports.Add(FoundationJsonPath);
            entityTestEntityNestedProjectionDoc.Imports.Add("TestSource.cdm.json");
            entityTestEntityNestedProjectionDoc.Definitions.Add(entityTestEntityNestedProjection);

            localRoot.Documents.Add(entityTestEntityNestedProjectionDoc, entityTestEntityNestedProjectionDoc.Name);
            manifestDefault.Entities.Add(entityTestEntityNestedProjection);

            return(entityTestEntityNestedProjection);
        }
Ejemplo n.º 5
0
        public void Process(TraitAnnotation annotation)
        {
            string            traitName = annotation.Value;
            CdmTraitReference trait     = corpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, traitName, false);

            foreach (var argument in annotation.Arguments)
            {
                if (argument.Value != null)
                {
                    trait.Arguments.Add(argument.Key, argument.Value);
                }
            }

            attribute.AppliedTraits.Add(trait);
        }
Ejemplo n.º 6
0
        public async Task TestMissingPersistenceFormat()
        {
            var expectedLogCodes = new HashSet <CdmLogCode> {
                CdmLogCode.ErrPersistClassMissing
            };
            CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, "TestMissingPersistenceFormat", expectedCodes: expectedLogCodes);

            CdmFolderDefinition folder = corpus.Storage.FetchRootFolder(corpus.Storage.DefaultNamespace);

            CdmManifestDefinition manifest = corpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "someManifest");

            folder.Documents.Add(manifest);
            // trying to save to an unsupported format should return false and not fail
            bool succeded = await manifest.SaveAsAsync("manifest.unSupportedExtension");

            Assert.IsFalse(succeded);
        }
Ejemplo n.º 7
0
        private static async Task SaveCDMDocuments(string nameSpace, CdmCorpusDefinition cdmCorpus)
        {
            Console.WriteLine("Make placeholder manifest");
            // Make the temp manifest and add it to the root of the local documents in the corpus
            CdmManifestDefinition manifestAbstract = cdmCorpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "tempAbstract");

            // Add the temp manifest to the root of the local documents in the corpus.
            var localRoot = cdmCorpus.Storage.FetchRootFolder(nameSpace);

            localRoot.Documents.Add(manifestAbstract);

            // Create two entities from scratch, and add some attributes, traits, properties, and relationships in between
            Console.WriteLine("Create net new entities");

            DTDLParser parser = new DTDLParser(dtdlRoot, "json");

            foreach (DTInterfaceInfo info in parser.DTDLInterfaces)
            {
                CreateCustomEntity(cdmCorpus, manifestAbstract, localRoot, info);
            }

            // Create the resolved version of everything in the root folder too
            Console.WriteLine("Resolve the placeholder");
            var manifestResolved = await manifestAbstract.CreateResolvedManifestAsync("default", null);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            manifestResolved.Imports.Add("cdm:/foundations.cdm.json");

            Console.WriteLine($"Save the folders and partition data documents to {nameSpace} storage.");
            await SavePartitionDocuments(nameSpace, cdmCorpus, manifestResolved);

            Console.WriteLine($"Save the manifest, entity and resolved documents to {nameSpace} storage.");
            // Save all other files (resolved, manifest, entity etc.)

            var manifestFileName = $"{manifestResolved.ManifestName}.manifest.cdm.json";
            var manifestSaved    = await manifestResolved.SaveAsAsync(manifestFileName, true);

            LogSaveOutput(manifestSaved, manifestFileName);

            var modelFileName = "model.json";
            var modelSaved    = await manifestResolved.SaveAsAsync(modelFileName, true);

            LogSaveOutput(modelSaved, modelFileName);
        }
Ejemplo n.º 8
0
        public async Task <List <string> > InitializeCdmFolderAsync(IEnumerable <TabularMappingDefinition> tabularMappings, string rootFolder = "local")
        {
            _cdmCorpusDefinition.SetEventCallback(null, CdmStatusLevel.None);
            CdmManifestDefinition manifestAbstract = _cdmCorpusDefinition.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "tempAbstract");

            var localRoot = _cdmCorpusDefinition.Storage.FetchRootFolder(rootFolder);

            localRoot.Documents.Add(manifestAbstract);

            List <string> entities = await BuildCdmEntitys(_cdmCorpusDefinition, manifestAbstract, localRoot, tabularMappings);

            CdmManifestDefinition manifestResolved = await CreateResolvedManifest(manifestAbstract);

            await CreateDataPatitions(_cdmCorpusDefinition, manifestResolved);

            await manifestResolved.SaveAsAsync($"{manifestResolved.ManifestName}.manifest.cdm.json", true);

            return(entities);
        }
Ejemplo n.º 9
0
        private async static Task <CdmManifestDefinition> LoadAndResolveManifest(CdmCorpusDefinition corpus, CdmManifestDefinition manifest, string renameSuffix)
        {
            Console.WriteLine("Resolving manifest " + manifest.ManifestName + " ...");
            CdmManifestDefinition resolvedManifest = await manifest.CreateResolvedManifestAsync(manifest.ManifestName + renameSuffix, "{n}-resolved.cdm.json");

            foreach (CdmManifestDeclarationDefinition subManifestDecl in manifest.SubManifests)
            {
                CdmManifestDefinition subManifest = await corpus.FetchObjectAsync <CdmManifestDefinition>(subManifestDecl.Definition, manifest);

                CdmManifestDefinition resolvedSubManifest = await LoadAndResolveManifest(corpus, subManifest, renameSuffix);

                CdmManifestDeclarationDefinition resolvedDecl = corpus.MakeObject <CdmManifestDeclarationDefinition>(CdmObjectType.ManifestDeclarationDef, resolvedSubManifest.ManifestName);
                resolvedDecl.Definition = corpus.Storage.CreateRelativeCorpusPath(resolvedSubManifest.AtCorpusPath, resolvedManifest);

                resolvedManifest.SubManifests.Add(resolvedDecl);
            }

            return(resolvedManifest);
        }
Ejemplo n.º 10
0
        public IEnumerable <CdmE2ERelationship> GenerateRelationships(Table table)
        {
            var fkColumns = table.Columns.Where(t => t.IsForeignKey);

            foreach (var column in fkColumns)
            {
                var relationshipName = $"relationship-{table.Name}-{column.Name}";
                var relationship     = corpus.MakeObject <CdmE2ERelationship>(CdmObjectType.E2ERelationshipDef, relationshipName);

                string fromDocumentName = resolver.GetDocumentFileName(table.Name);
                relationship.FromEntity          = $"{fromDocumentName}/{table.Name}";
                relationship.FromEntityAttribute = column.Name;

                string toDocumentName = resolver.GetDocumentFileName(column.ForeignKey.Table.Name);
                relationship.ToEntity          = $"{toDocumentName}/{column.ForeignKey.Table.Name}";
                relationship.ToEntityAttribute = column.ForeignKey.Name;

                yield return(relationship);
            }
        }
Ejemplo n.º 11
0
        public void TestCdmCollectionAddingList()
        {
            var cdmCorpus = new CdmCorpusDefinition();

            cdmCorpus.Storage.DefaultNamespace = "local";
            cdmCorpus.Storage.Mount("local", new LocalAdapter("CdmCorpus/LocalPath"));

            var ctx = cdmCorpus.Ctx;

            var cdmDocument = new CdmDocumentDefinition(ctx, "NameOfDocument");
            var collection  = new CdmCollection <CdmEntityDeclarationDefinition>(ctx, cdmDocument, Enums.CdmObjectType.LocalEntityDeclarationDef);

            var entityList = new List <CdmEntityDeclarationDefinition>();

            for (int i = 0; i < 2; i++)
            {
                var entity = new CdmEntityDefinition(cdmCorpus.Ctx, $"entityName_{i}", null);

                CdmCollectionHelperFunctions.CreateDocumentForEntity(cdmCorpus, entity);

                var entityDeclaration = cdmCorpus.MakeObject <CdmEntityDeclarationDefinition>(Enums.CdmObjectType.LocalEntityDeclarationDef, entity.EntityName, false);
                entityDeclaration.Owner      = entity.Owner;
                entityDeclaration.EntityPath = $"{entity.Owner.AtCorpusPath}/{entity.EntityName}";

                entityList.Add(entityDeclaration);
            }
            Assert.AreEqual(0, collection.Count);

            collection.AddRange(entityList);

            Assert.AreEqual(2, collection.Count);

            for (int i = 0; i < 2; i++)
            {
                Assert.AreEqual($"entityName_{i}", collection[i].EntityName);
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Creates a source entity for a projection
        /// </summary>
        public static CdmEntityDefinition CreateSourceEntity(CdmCorpusDefinition corpus, CdmFolderDefinition localRoot)
        {
            string entityName          = "SourceEntity";
            CdmEntityDefinition entity = corpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, entityName);

            string attributeName1 = "id";
            CdmTypeAttributeDefinition attribute1 = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, attributeName1);

            attribute1.DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "string", true);
            entity.Attributes.Add(attribute1);

            string attributeName2 = "name";
            CdmTypeAttributeDefinition attribute2 = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, attributeName2);

            attribute2.DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "string", true);
            entity.Attributes.Add(attribute2);

            string attributeName3 = "value";
            CdmTypeAttributeDefinition attribute3 = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, attributeName3);

            attribute3.DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "integer", true);
            entity.Attributes.Add(attribute3);

            string attributeName4 = "date";
            CdmTypeAttributeDefinition attribute4 = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, attributeName4);

            attribute4.DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "date", true);
            entity.Attributes.Add(attribute4);

            CdmDocumentDefinition entityDoc = corpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{entityName}.cdm.json", false);

            entityDoc.Imports.Add(foundationJsonPath);
            entityDoc.Definitions.Add(entity);
            localRoot.Documents.Add(entityDoc, entityDoc.Name);

            return(entity);
        }
Ejemplo n.º 13
0
        public async Task TestEntityAttributeProjUsingObjectModel()
        {
            CdmCorpusDefinition corpus = ProjectionTestUtils.GetLocalCorpus(testsSubpath, "TestEntityAttributeProjUsingObjectModel");

            corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestEntityAttributeProjUsingObjectModel")));
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            // Create an ArrayExpansion operation
            CdmOperationArrayExpansion arrayExpansionOp = corpus.MakeObject <CdmOperationArrayExpansion>(CdmObjectType.OperationArrayExpansionDef);

            arrayExpansionOp.StartOrdinal = 1;
            arrayExpansionOp.EndOrdinal   = 2;
            projection.Operations.Add(arrayExpansionOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create another projection that does a rename so that we can see the expanded attributes in the final resolved entity
            CdmProjection projection2 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            projection2.Source = projectionEntityRef;

            // Create a RenameAttributes operation
            CdmOperationRenameAttributes renameAttrsOp = corpus.MakeObject <CdmOperationRenameAttributes>(CdmObjectType.OperationRenameAttributesDef);

            renameAttrsOp.RenameFormat = "{m}{o}";
            projection2.Operations.Add(renameAttrsOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef2 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef2.ExplicitReference = projection2;

            // Create an entity attribute that contains this projection and add this to the entity
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef2;
            entity.Attributes.Add(entityAttribute);

            // Resolve the entity
            CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot);

            // Verify correctness of the resolved attributes after running the projections
            // Original set of attributes: ["id", "name", "value", "date"]
            // Expand 1...2, renameFormat = {m}{o}
            Assert.AreEqual(8, resolvedEntity.Attributes.Count);
            Assert.AreEqual("id1", (resolvedEntity.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name1", (resolvedEntity.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value1", (resolvedEntity.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date1", (resolvedEntity.Attributes[3] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("id2", (resolvedEntity.Attributes[4] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name2", (resolvedEntity.Attributes[5] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value2", (resolvedEntity.Attributes[6] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date2", (resolvedEntity.Attributes[7] as CdmTypeAttributeDefinition).Name);
        }
Ejemplo n.º 14
0
        static async Task Main()
        {
            // Make a corpus, the corpus is the collection of all documents and folders created or discovered while navigating objects and paths
            var cdmCorpus = new CdmCorpusDefinition();

            Console.WriteLine("configure storage adapters");

            // Configure storage adapters to point at the target local manifest location and at the fake public standards
            var pathFromExeToExampleRoot = "../../../../../../";


            cdmCorpus.Storage.Mount("local", new LocalAdapter(pathFromExeToExampleRoot + "6-create-net-new-entities"));
            cdmCorpus.Storage.DefaultNamespace = "local"; // local is our default. so any paths that start out navigating without a device tag will assume local

            // Fake cdm, normaly use the github adapter
            // Mount it as the 'cdm' device, not the default so must use "cdm:/folder" to get there
            cdmCorpus.Storage.Mount("cdm", new LocalAdapter(pathFromExeToExampleRoot + "example-public-standards"));

            // Example how to mount to the ADLS.
            // cdmCorpus.Storage.Mount("adls",
            //    new ADLSAdapter(
            // "<ACCOUNT-NAME>.dfs.core.windows.net", // Hostname.
            // "/<FILESYSTEM-NAME>", // Root.
            // "72f988bf-86f1-41af-91ab-2d7cd011db47",  // Tenant ID.
            // "<CLIENT-ID>",  // Client ID.
            // "<CLIENT-SECRET>" // Client secret.
            // ));

            Console.WriteLine("Make placeholder manifest");
            // Make the temp manifest and add it to the root of the local documents in the corpus
            CdmManifestDefinition manifestAbstract = cdmCorpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "tempAbstract");

            // Add the temp manifest to the root of the local documents in the corpus
            var localRoot = cdmCorpus.Storage.FetchRootFolder("local");

            localRoot.Documents.Add(manifestAbstract, "TempAbstract.manifest.cdm.json");

            // Create two entities from scratch, and add some attributes, traits, properties, and relationships in between
            Console.WriteLine("Create net new entities");


            // Create the simplest entity - CustomPerson
            // Create the entity definition instance
            var personEntity = cdmCorpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, CustomPersonEntityName, false);
            // Add type attributes to the entity instance
            var personAttributeId = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomPersonEntityName}Id", "identifiedBy", "entityId");

            personEntity.Attributes.Add(personAttributeId);
            var personAttributeName = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomPersonEntityName}Name", "hasA", "string");

            personEntity.Attributes.Add(personAttributeName);
            // Add properties to the entity instance
            personEntity.DisplayName = CustomPersonEntityName;
            personEntity.Version     = "0.0.1";
            personEntity.Description = "This is a custom entity created for the sample.";
            // Create the document which contains the entity
            var personEntityDoc = cdmCorpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{CustomPersonEntityName}.cdm.json", false);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            personEntityDoc.Imports.Add(FoundationJsonPath);
            personEntityDoc.Definitions.Add(personEntity);
            // Add the document to the root of the local documents in the corpus
            localRoot.Documents.Add(personEntityDoc, personEntityDoc.Name);
            // Add the entity to the manifest
            manifestAbstract.Entities.Add(personEntity);


            // Create an entity - CustomAccount which has a relationship with the entity CustomPerson
            // Create the entity definition instance
            var accountEntity = cdmCorpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, CustomAccountEntityName, false);
            // Add type attributes to the entity instance
            var accountAttributeId = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomAccountEntityName}Id", "identifiedBy", "entityId");

            accountEntity.Attributes.Add(accountAttributeId);
            var accountAttributeName = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomAccountEntityName}Name", "hasA", "string");

            accountEntity.Attributes.Add(accountAttributeName);
            // Add properties to the entity instance
            accountEntity.DisplayName = CustomAccountEntityName;
            accountEntity.Version     = "0.0.1";
            accountEntity.Description = "This is a custom entity created for the sample.";
            // In this sample, every account has one person who owns the account
            // the relationship is actually an entity attribute
            var attributeExplanation = "The owner of the account, which is a person.";
            // You can all CreateSimpleAttributeForRelationshipBetweenTwoEntities() instead, but CreateAttributeForRelationshipBetweenTwoEntities() can show
            // more details of how to use resolution guidance to customize your data
            var accountOwnerAttribute = CreateAttributeForRelationshipBetweenTwoEntities(cdmCorpus, CustomPersonEntityName, "accountOwner", attributeExplanation);

            accountEntity.Attributes.Add(accountOwnerAttribute);
            // Create the document which contains the entity
            var accountEntityDoc = cdmCorpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{CustomAccountEntityName}.cdm.json", false);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            accountEntityDoc.Imports.Add(FoundationJsonPath);
            // the CustomAccount entity has a relationship with the CustomPerson entity, this relationship is defined from its attribute with traits,
            // the import to the entity reference CustomPerson's doc is required
            accountEntityDoc.Imports.Add($"{CustomPersonEntityName}.cdm.json");
            accountEntityDoc.Definitions.Add(accountEntity);
            // Add the document to the root of the local documents in the corpus
            localRoot.Documents.Add(accountEntityDoc, accountEntityDoc.Name);
            // Add the entity to the manifest
            manifestAbstract.Entities.Add(accountEntity);


            // Create an entity which extends "Account" from the standard, it contains everything that "Account" has
            var extendedStandardAccountEntity = cdmCorpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, ExtendedStandardAccount, false);

            // This function with 'true' will make a simple reference to the base
            extendedStandardAccountEntity.ExtendsEntity = cdmCorpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, "Account", true);
            var attrExplanation = "This is a simple custom account for this sample.";
            // Add a relationship from it to the CustomAccount entity, and name the foreign key to SimpleCustomAccount
            // You can all CreateSimpleAttributeForRelationshipBetweenTwoEntities() instead, but CreateAttributeForRelationshipBetweenTwoEntities() can show
            // more details of how to use resolution guidance to customize your data
            var simpleCustomAccountAttribute = CreateAttributeForRelationshipBetweenTwoEntities(cdmCorpus, CustomAccountEntityName, "SimpleCustomAccount", attrExplanation);

            extendedStandardAccountEntity.Attributes.Add(simpleCustomAccountAttribute);
            var extendedStandardAccountntityDoc = cdmCorpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{ExtendedStandardAccount}.cdm.json", false);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            extendedStandardAccountntityDoc.Imports.Add(FoundationJsonPath);
            // The ExtendedAccount entity extends from the "Account" entity from standards, the import to the entity Account's doc is required
            // it also has a relationship with the CustomAccount entity, the relationship defined from its from its attribute with traits, the import to the entity reference CustomAccount's doc is required
            extendedStandardAccountntityDoc.Imports.Add($"{SchemaDocsRoot}/Account.cdm.json");
            extendedStandardAccountntityDoc.Imports.Add($"{CustomAccountEntityName}.cdm.json");
            // Add the document to the root of the local documents in the corpus
            localRoot.Documents.Add(extendedStandardAccountntityDoc, extendedStandardAccountntityDoc.Name);
            extendedStandardAccountntityDoc.Definitions.Add(extendedStandardAccountEntity);
            // Add the entity to the manifest
            manifestAbstract.Entities.Add(extendedStandardAccountEntity);


            // Create the resolved version of everything in the root folder too
            Console.WriteLine("Resolve the placeholder");
            var manifestResolved = await manifestAbstract.CreateResolvedManifestAsync("default", null);

            Console.WriteLine("Save the docs");
            foreach (CdmEntityDeclarationDefinition eDef in manifestResolved.Entities)
            {
                // Get the entity being pointed at
                var localEDef = eDef;
                var entDef    = await cdmCorpus.FetchObjectAsync <CdmEntityDefinition>(localEDef.EntityPath, manifestResolved);

                // Make a fake partition, just to demo that
                var part = cdmCorpus.MakeObject <CdmDataPartitionDefinition>(CdmObjectType.DataPartitionDef, $"{entDef.EntityName}-data-description");
                localEDef.DataPartitions.Add(part);
                part.Explanation = "not real data, just for demo";
                // We have existing partition files for the custom entities, so we need to make the partition point to the file location
                part.Location = $"local:/{entDef.EntityName}/partition-data.csv";
                // Add trait to partition for csv params
                var csvTrait = part.ExhibitsTraits.Add("is.partition.format.CSV", false);
                csvTrait.Arguments.Add("columnHeaders", "true");
                csvTrait.Arguments.Add("delimiter", ",");
            }

            // We can save the docs as manifest.cdm.json format or model.json
            // Save as manifest.cdm.json
            await manifestResolved.SaveAsAsync($"{manifestResolved.ManifestName}.manifest.cdm.json", true);

            // Save as a model.json
            // await manifestResolved.SaveAsAsync("model.json", true);
        }
Ejemplo n.º 15
0
        static async Task Main(string[] args)
        {
            // Make a corpus, the corpus is the collection of all documents and folders created or discovered while navigating objects and paths
            var cdmCorpus = new CdmCorpusDefinition();

            Console.WriteLine("Configure storage adapters");

            // Configure storage adapters to point at the target local manifest location and at the fake public standards
            string pathFromExeToExampleRoot = "../../../../../../";

            cdmCorpus.Storage.Mount("local", new LocalAdapter(pathFromExeToExampleRoot + "2-create-manifest"));
            cdmCorpus.Storage.DefaultNamespace = "local"; // local is our default. so any paths that start out navigating without a device tag will assume local

            // Fake cdm, normaly use the github adapter
            // Mount it as the 'cdm' device, not the default so must use "cdm:/folder" to get there
            cdmCorpus.Storage.Mount("cdm", new LocalAdapter(pathFromExeToExampleRoot + "example-public-standards"));

            // Example how to mount to the ADLS.
            // cdmCorpus.Storage.Mount("adls",
            //    new ADLSAdapter(
            // "<ACCOUNT-NAME>.dfs.core.windows.net", // Hostname.
            // "/<FILESYSTEM-NAME>", // Root.
            // "72f988bf-86f1-41af-91ab-2d7cd011db47",  // Tenant ID.
            // "<CLIENT-ID>",  // Client ID.
            // "<CLIENT-SECRET>" // Client secret.
            // ));

            Console.WriteLine("Make placeholder manifest");
            // Make the temp manifest and add it to the root of the local documents in the corpus
            CdmManifestDefinition manifestAbstract = cdmCorpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "tempAbstract");

            // Add each declaration, this example is about medical appointments and care plans
            manifestAbstract.Entities.Add("Account", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Account.cdm.json/Account");
            manifestAbstract.Entities.Add("Address", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Address.cdm.json/Address");
            manifestAbstract.Entities.Add("CarePlan", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/CarePlan.cdm.json/CarePlan");
            manifestAbstract.Entities.Add("CodeableConcept", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/CodeableConcept.cdm.json/CodeableConcept");
            manifestAbstract.Entities.Add("Contact", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Contact.cdm.json/Contact");
            manifestAbstract.Entities.Add("Device", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Device.cdm.json/Device");
            manifestAbstract.Entities.Add("EmrAppointment", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/EmrAppointment.cdm.json/EmrAppointment");
            manifestAbstract.Entities.Add("Encounter", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Encounter.cdm.json/Encounter");
            manifestAbstract.Entities.Add("EpisodeOfCare", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/EpisodeOfCare.cdm.json/EpisodeOfCare");
            manifestAbstract.Entities.Add("Location", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Location.cdm.json/Location");

            // Add the temp manifest to the root of the local documents in the corpus.
            var localRoot = cdmCorpus.Storage.FetchRootFolder("local");

            localRoot.Documents.Add(manifestAbstract);

            // Create the resolved version of everything in the root folder too
            Console.WriteLine("Resolve the placeholder");
            var manifestResolved = await manifestAbstract.CreateResolvedManifestAsync("default", "");

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            manifestResolved.Imports.Add("cdm:/foundations.cdm.json");

            Console.WriteLine("Save the documents");
            foreach (CdmEntityDeclarationDefinition eDef in manifestResolved.Entities)
            {
                // Get the entity being pointed at
                var localEDef = eDef;
                var entDef    = await cdmCorpus.FetchObjectAsync <CdmEntityDefinition>(localEDef.EntityPath, manifestResolved);

                // Make a fake partition, just to demo that
                var part = cdmCorpus.MakeObject <CdmDataPartitionDefinition>(CdmObjectType.DataPartitionDef, $"{entDef.EntityName}-data-description");
                localEDef.DataPartitions.Add(part);
                part.Explanation = "not real data, just for demo";

                // Define the location of the partition, relative to the manifest
                var location = $"local:/{entDef.EntityName}/partition-data.csv";
                part.Location = cdmCorpus.Storage.CreateRelativeCorpusPath(location, manifestResolved);

                // Add trait to partition for csv params
                var csvTrait = part.ExhibitsTraits.Add("is.partition.format.CSV", false);
                csvTrait.Arguments.Add("columnHeaders", "true");
                csvTrait.Arguments.Add("delimiter", ",");

                // Get the actual location of the partition file from the corpus
                string partPath = cdmCorpus.Storage.CorpusPathToAdapterPath(location);

                // Make a fake file with nothing but header for columns
                string header = "";
                foreach (CdmTypeAttributeDefinition att in entDef.Attributes)
                {
                    if (header != "")
                    {
                        header += ",";
                    }
                    header += att.Name;
                }

                Directory.CreateDirectory(cdmCorpus.Storage.CorpusPathToAdapterPath($"local:/{ entDef.EntityName}"));
                File.WriteAllText(partPath, header);
            }

            await manifestResolved.SaveAsAsync($"{manifestResolved.ManifestName}.manifest.cdm.json", true);
        }
Ejemplo n.º 16
0
        private async Task CreateManifest(CdmCorpusDefinition cdmCorpus)
        {
            Console.WriteLine("Make placeholder manifest");
            // Make the temp manifest and add it to the root of the local documents in the corpus
            CdmManifestDefinition manifestAbstract = cdmCorpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "tempAbstract");

            // Add each declaration, this example is about medical appointments and care plans
            manifestAbstract.Entities.Add("Account", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Account.cdm.json/Account");
            manifestAbstract.Entities.Add("Address", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Address.cdm.json/Address");
            manifestAbstract.Entities.Add("CarePlan", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/CarePlan.cdm.json/CarePlan");
            manifestAbstract.Entities.Add("CodeableConcept", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/CodeableConcept.cdm.json/CodeableConcept");
            manifestAbstract.Entities.Add("Contact", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Contact.cdm.json/Contact");
            manifestAbstract.Entities.Add("Device", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Device.cdm.json/Device");
            manifestAbstract.Entities.Add("EmrAppointment", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/EmrAppointment.cdm.json/EmrAppointment");
            manifestAbstract.Entities.Add("Encounter", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Encounter.cdm.json/Encounter");
            manifestAbstract.Entities.Add("EpisodeOfCare", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/EpisodeOfCare.cdm.json/EpisodeOfCare");
            manifestAbstract.Entities.Add("Location", "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Location.cdm.json/Location");

            // Add the temp manifest to the root of the local documents in the corpus.
            var localRoot = cdmCorpus.Storage.FetchRootFolder("local");

            localRoot.Documents.Add(manifestAbstract);

            // Create the resolved version of everything in the root folder too
            Console.WriteLine("Resolve the placeholder");
            var manifestResolved = await manifestAbstract.CreateResolvedManifestAsync("default", "");

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            manifestResolved.Imports.Add("cdm:/foundations.cdm.json");

            Console.WriteLine("Save the documents");
            foreach (CdmEntityDeclarationDefinition eDef in manifestResolved.Entities)
            {
                // Get the entity being pointed at
                var localEDef = eDef;
                var entDef    = await cdmCorpus.FetchObjectAsync <CdmEntityDefinition>(localEDef.EntityPath, manifestResolved);

                // Make a fake partition, just to demo that
                var part = cdmCorpus.MakeObject <CdmDataPartitionDefinition>(CdmObjectType.DataPartitionDef, $"{entDef.EntityName}-data-description");
                localEDef.DataPartitions.Add(part);
                part.Explanation = "not real data, just for demo";

                // Define the location of the partition, relative to the manifest
                var location = $"local:/{entDef.EntityName}/partition-data.csv";
                part.Location = cdmCorpus.Storage.CreateRelativeCorpusPath(location, manifestResolved);

                // Add trait to partition for csv params
                var csvTrait = part.ExhibitsTraits.Add("is.partition.format.CSV", false) as CdmTraitReference;
                csvTrait.Arguments.Add("columnHeaders", "true");
                csvTrait.Arguments.Add("delimiter", ",");

                // Get the actual location of the partition file from the corpus
                string partPath = cdmCorpus.Storage.CorpusPathToAdapterPath(location);

                // Make a fake file with nothing but header for columns
                string header = "";
                foreach (CdmTypeAttributeDefinition att in entDef.Attributes)
                {
                    if (header != "")
                    {
                        header += ",";
                    }
                    header += att.Name;
                }

                Directory.CreateDirectory(cdmCorpus.Storage.CorpusPathToAdapterPath($"local:/{entDef.EntityName}"));
                File.WriteAllText(partPath, header);
            }

            await manifestResolved.SaveAsAsync($"{manifestResolved.ManifestName}.manifest.cdm.json", true);
        }
        public async Task TestConditionalProjUsingObjectModel()
        {
            string testName               = "TestConditionalProjUsingObjectModel";
            CdmCorpusDefinition corpus    = ProjectionTestUtils.GetCorpus(testName, testsSubpath);
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity.
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection with a condition that states the operation should only execute when the resolution directive is 'structured'.
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            projection.Condition = "structured==true";

            // Create an AddAttributeGroup operation
            CdmOperationAddAttributeGroup addAttGroupOp = corpus.MakeObject <CdmOperationAddAttributeGroup>(CdmObjectType.OperationAddAttributeGroupDef);

            addAttGroupOp.AttributeGroupName = "PersonAttributeGroup";
            projection.Operations.Add(addAttGroupOp);

            // Create an entity reference to hold this projection.
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create an entity attribute that contains this projection and add this to the entity.
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef;
            entity.Attributes.Add(entityAttribute);

            // Create resolution options with the 'referenceOnly' directive.
            ResolveOptions resOpt = new ResolveOptions(entity.InDocument)
            {
                Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                    "referenceOnly"
                })
            };

            // Resolve the entity with 'referenceOnly'
            CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Verify correctness of the resolved attributes after running the AddAttributeGroup operation
            // Original set of attributes: ["id", "name", "value", "date"]
            // Condition not met, keep attributes in flat list
            Assert.AreEqual(4, resolvedEntityWithReferenceOnly.Attributes.Count);
            Assert.AreEqual("id", (resolvedEntityWithReferenceOnly.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (resolvedEntityWithReferenceOnly.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (resolvedEntityWithReferenceOnly.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (resolvedEntityWithReferenceOnly.Attributes[3] as CdmTypeAttributeDefinition).Name);

            // Now resolve the entity with the 'structured' directive
            resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                "structured"
            });
            CdmEntityDefinition resolvedEntityWithStructured = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Verify correctness of the resolved attributes after running the AddAttributeGroup operation
            // Original set of attributes: ["id", "name", "value", "date"]
            // Condition met, put all attributes in an attribute group
            CdmAttributeGroupDefinition attGroupDefinition = this.ValidateAttributeGroup(resolvedEntityWithStructured.Attributes, "PersonAttributeGroup");

            Assert.AreEqual(4, attGroupDefinition.Members.Count);
            Assert.AreEqual("id", (attGroupDefinition.Members[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (attGroupDefinition.Members[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (attGroupDefinition.Members[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (attGroupDefinition.Members[3] as CdmTypeAttributeDefinition).Name);
        }
Ejemplo n.º 18
0
        public async Task TestConditionalProjUsingObjectModel()
        {
            string testName               = nameof(TestConditionalProjUsingObjectModel);
            CdmCorpusDefinition corpus    = TestHelper.GetLocalCorpus(testsSubpath, testName);
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            corpus.Storage.Mount("traitGroup", new LocalAdapter(traitGroupFilePath));

            // Create an entity.
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            entity.InDocument.Imports.Add("traitGroup:/TraitGroup.cdm.json");

            // Create a projection with a condition that states the operation should only execute when the resolution directive is 'structured'.
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            projection.Condition       = "structured==true";
            projection.RunSequentially = true;

            // Create an AlterTraits operation
            CdmOperationAlterTraits alterTraitsOp_1 = corpus.MakeObject <CdmOperationAlterTraits>(CdmObjectType.OperationAlterTraitsDef);

            alterTraitsOp_1.TraitsToAdd = new CdmCollection <CdmTraitReferenceBase>(corpus.Ctx, alterTraitsOp_1, CdmObjectType.TraitRef);
            alterTraitsOp_1.TraitsToAdd.Add(corpus.MakeRef <CdmTraitReference>(CdmObjectType.TraitRef, "means.TraitG100", true));
            alterTraitsOp_1.TraitsToAdd.Add(corpus.MakeRef <CdmTraitGroupReference>(CdmObjectType.TraitGroupRef, "JobTitleBase", true));
            alterTraitsOp_1.TraitsToRemove = new CdmCollection <CdmTraitReferenceBase>(corpus.Ctx, alterTraitsOp_1, CdmObjectType.TraitRef);
            alterTraitsOp_1.TraitsToRemove.Add(corpus.MakeRef <CdmTraitReference>(CdmObjectType.TraitRef, "means.TraitG300", true));
            projection.Operations.Add(alterTraitsOp_1);

            CdmOperationAlterTraits alterTraitsOp_2 = corpus.MakeObject <CdmOperationAlterTraits>(CdmObjectType.OperationAlterTraitsDef);
            var traitG4 = corpus.MakeRef <CdmTraitReference>(CdmObjectType.TraitRef, "means.TraitG4", true);

            traitG4.Arguments.Add("precision", "5");
            traitG4.Arguments.Add("scale", "15");
            alterTraitsOp_2.TraitsToAdd = new CdmCollection <CdmTraitReferenceBase>(corpus.Ctx, alterTraitsOp_2, CdmObjectType.TraitRef);
            alterTraitsOp_2.TraitsToAdd.Add(traitG4);
            alterTraitsOp_2.ApplyTo = new List <string>()
            {
                "name"
            };
            projection.Operations.Add(alterTraitsOp_2);

            // Create an entity reference to hold this projection.
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create an entity attribute that contains this projection and add this to the entity.
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef;
            entity.Attributes.Add(entityAttribute);

            // Create resolution options with the 'referenceOnly' directive.
            ResolveOptions resOpt = new ResolveOptions(entity.InDocument)
            {
                Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                    "referenceOnly"
                })
            };
            CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Original set of attributes: ["name", "age", "address", "phoneNumber", "email"]
            // Condition not met, no traits are added
            Assert.AreEqual(4, resolvedEntityWithReferenceOnly.Attributes.Count);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[0], "id", doesNotExist: true);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[1], "name", doesNotExist: true);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[2], "value", doesNotExist: true);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[3], "date", doesNotExist: true);

            CdmEntityDefinition resolvedEntityWithStructured = await ProjectionTestUtils.GetResolvedEntity(corpus, entity, new List <string> {
                "structured"
            });

            // Original set of attributes: ["name", "age", "address", "phoneNumber", "email"]
            // Condition met, new traits are added
            Assert.AreEqual(4, resolvedEntityWithStructured.Attributes.Count);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[0], "id");
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[1], "name", true);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[2], "value");
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[3], "date");
        }
Ejemplo n.º 19
0
        public async Task TestWithoutNesting()
        {
            CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, "TestEventList");

            corpus.SetEventCallback(eventCallback, CdmStatusLevel.Warning, DummyCorrelationId);

            // Test fetching an object from invalid namespace results in at least one error message in the recorder
            _ = await corpus.FetchObjectAsync <CdmDocumentDefinition>("foo:/bar");

            TestBasicLogsState(corpus);
            TestHelper.AssertCdmLogCodeEquality(corpus, CdmLogCode.ErrStorageNamespaceNotRegistered);

            // Test fetching a good object, this should leave event recorder empty
            _ = await corpus.FetchObjectAsync <CdmDocumentDefinition>("local:/default.manifest.cdm.json");

            TestNoLogsState(corpus);

            // Test saving a manifest to invalid namespace results in at least one error message in the recorder
            var manifest = corpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "dummy");
            await manifest.SaveAsAsync("foo:/bar", true);

            TestBasicLogsState(corpus);
            TestHelper.AssertCdmLogCodeEquality(corpus, CdmLogCode.ErrValdnMissingDoc);

            // Test resolving a manifest not added to a folder, this should yield at least one error message in the recorder
            await manifest.CreateResolvedManifestAsync("new dummy", null);

            TestBasicLogsState(corpus);
            TestHelper.AssertCdmLogCodeEquality(corpus, CdmLogCode.ErrResolveManifestFailed);

            // Test resolving an entity without WRT doc, this should yield at least one error message in the recorder
            var entity2 = corpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, "MyEntity2");
            await entity2.CreateResolvedEntityAsync("MyEntity2-Resolved");

            TestBasicLogsState(corpus);
            TestHelper.AssertCdmLogCodeEquality(corpus, CdmLogCode.ErrDocWrtDocNotfound);

            // Test invoking FileStatusCheckAsync on the manifest, this should yield at least one error message in the recorder
            await manifest.FileStatusCheckAsync();

            TestBasicLogsState(corpus);
            TestHelper.AssertCdmLogCodeEquality(corpus, CdmLogCode.ErrStorageNullNamespace);

            // Repeat the same test but with status level 'None', no events should be recorded
            corpus.Ctx.ReportAtLevel = CdmStatusLevel.None;
            await entity2.CreateResolvedEntityAsync("MyEntity2-Resolved");

            TestNoLogsState(corpus);

            // Test checking file status on a data partition
            // We're at log level 'Progress', so we get the EnterScope/LeaveScope messages too
            corpus.Ctx.ReportAtLevel = CdmStatusLevel.Progress;
            var part = corpus.MakeObject <CdmDataPartitionDefinition>(CdmObjectType.DataPartitionDef, "part");
            await part.FileStatusCheckAsync();

            TestBasicLogsState(corpus);
            TestHelper.AssertCdmLogCodeEquality(corpus, CdmLogCode.ErrPathNullObjectPath);

            // Test checking file status on a data partition pattern
            var refDoc      = corpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, "RefEntDoc");
            var partPattern = corpus.MakeObject <CdmDataPartitionPatternDefinition>(CdmObjectType.DataPartitionPatternDef, "partPattern");

            partPattern.InDocument = refDoc;
            await partPattern.FileStatusCheckAsync();

            TestBasicLogsState(corpus);
            TestHelper.AssertCdmLogCodeEquality(corpus, CdmLogCode.ErrStorageNullNamespace);
            TestHelper.AssertCdmLogCodeEquality(corpus, CdmLogCode.ErrDocAdapterNotFound);

            // Test calculating relationships - no errors/warnings
            await corpus.CalculateEntityGraphAsync(manifest);

            TestBasicLogsState(corpus);

            // Test populating relationships in manifest - no errors/warnings
            await manifest.PopulateManifestRelationshipsAsync();

            TestBasicLogsState(corpus);
        }
Ejemplo n.º 20
0
        static async Task Main(string[] args)
        {
            // Make a corpus, the corpus is the collection of all documents and folders created or discovered while navigating objects and paths
            var cdmCorpus = new CdmCorpusDefinition();

            Console.WriteLine("Configure storage adapters");

            // Configure storage adapters to point at the target local manifest location and at the fake public standards
            string pathFromExeToExampleRoot = "../../../../../../";
            string sampleEntityName         = "Account";

            // Mount is as a local device.
            cdmCorpus.Storage.Mount("local", new LocalAdapter(pathFromExeToExampleRoot + "7-search-partition-pattern"));
            cdmCorpus.Storage.DefaultNamespace = "local"; // local is our default. so any paths that start out navigating without a device tag will assume local

            // Fake cdm, normaly use the github adapter
            // Mount it as the 'cdm' device, not the default so must use "cdm:/folder" to get there
            cdmCorpus.Storage.Mount("cdm", new LocalAdapter(pathFromExeToExampleRoot + "example-public-standards"));

            // Example how to mount to the ADLS.
            // cdmCorpus.Storage.Mount("adls",
            //    new ADLSAdapter(
            // "<ACCOUNT-NAME>.dfs.core.windows.net", // Hostname.
            // "/<FILESYSTEM-NAME>", // Root.
            // "72f988bf-86f1-41af-91ab-2d7cd011db47",  // Tenant ID.
            // "<CLIENT-ID>",  // Client ID.
            // "<CLIENT-SECRET>" // Client secret.
            // ));

            Console.WriteLine("Make placeholder manifest");
            // make the temp manifest and add it to the root of the local documents in the corpus
            CdmManifestDefinition manifestAbstract = cdmCorpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "tempAbstract");

            // Add the temp manifest to the root of the local documents in the corpus.
            var localRoot = cdmCorpus.Storage.FetchRootFolder("local");

            localRoot.Documents.Add(manifestAbstract, "tempAbstract.manifest.cdm.json");

            // Add an entity named Account from some public standards
            Console.WriteLine("Add an entity named Account from some public standards");
            var personDeclarationDefinition = manifestAbstract.Entities.Add(sampleEntityName, "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Account.cdm.json/Account");

            // Create a data partition pattern
            var dataPartitionPattern = cdmCorpus.MakeObject <CdmDataPartitionPatternDefinition>(CdmObjectType.DataPartitionPatternDef, "sampleDataPartitionPattern", false);

            dataPartitionPattern.RootLocation      = "local:dataFiles";
            dataPartitionPattern.RegularExpression = "/(\\d{4})/(\\w+)/cohort(\\d+)\\.csv$";
            Console.WriteLine($"    Assign regular expression of the data partition pattern to: {dataPartitionPattern.RegularExpression}");
            Console.WriteLine($"    Assign root location of the data partition pattern to: {dataPartitionPattern.RootLocation}");
            dataPartitionPattern.Explanation = "/ capture 4 digits / capture a word / capture one or more digits after the word cohort but before .csv";
            dataPartitionPattern.Parameters  = new List <string> {
                "year", "month", "cohortNumber"
            };

            // Add the data partition pattern we just created to the entity data partition pattern collection
            personDeclarationDefinition.DataPartitionPatterns.Add(dataPartitionPattern);

            // Calling FileStatusCheckAsync to pick up the all data partition files which names match the data partition pattern,
            // and add them to the entity in the manifest
            await manifestAbstract.FileStatusCheckAsync();

            // List all data partition locations.
            Console.WriteLine($"\nlist of all data partition locations for the entity Account matches the data partition pattern:");

            foreach (CdmDataPartitionDefinition dataPartition in personDeclarationDefinition.DataPartitions)
            {
                Console.WriteLine($"    {dataPartition.Location}");
            }

            Console.WriteLine("Resolve the manifest");
            var manifestResolved = await manifestAbstract.CreateResolvedManifestAsync("default", null);

            await manifestResolved.SaveAsAsync($"{manifestResolved.ManifestName}.manifest.cdm.json", true);

            // You can save the doc as a model.json format as an option
            // await manifestResolved.SaveAsAsync("model.json", true);
        }
Ejemplo n.º 21
0
        public async Task TestWithoutNesting()
        {
            CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, "TestEventList");

            corpus.SetEventCallback(eventCallback, CdmStatusLevel.Warning, DummyCorrelationId);

            // Test fetching an object from invalid namespace results in at least one error message in the recorder
            _ = await corpus.FetchObjectAsync <CdmDocumentDefinition>("foo:/bar");

            Assert.IsNotNull(corpus.Ctx.Events, "Ctx.Events should not be null");
            Assert.IsFalse(corpus.Ctx.Events.IsRecording, "Recording should be disabled at the end of API call");
            Assert.IsTrue(corpus.Ctx.Events.Count > 0, "There should have been at least one event recorded when fetching object with incorrect path");
            Assert.IsTrue(corpus.Ctx.Events[0].ContainsKey("timestamp"), "The recorded event should have had a timestamp key");
            Assert.IsTrue(corpus.Ctx.Events[0]["correlationId"] == DummyCorrelationId, "The recorded event should have had a correlationId key with the dummy value");

            // Test fetching a good object, this should leave event recorder empty
            _ = await corpus.FetchObjectAsync <CdmDocumentDefinition>("local:/default.manifest.cdm.json");

            Assert.IsFalse(corpus.Ctx.Events.IsRecording, "Recording should be disabled at the end of API call");
            Assert.IsTrue(corpus.Ctx.Events.Count == 0, "There should have been no events recorded when fetching object with correct path");

            // Test saving a manifest to invalid namespace results in at least one error message in the recorder
            var manifest = corpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "dummy");
            await manifest.SaveAsAsync("foo:/bar", true);

            Assert.IsFalse(corpus.Ctx.Events.IsRecording, "Recording should be disabled at the end of API call");
            Assert.IsTrue(corpus.Ctx.Events.Count > 0, "There should have been at least one event recorded");
            Assert.IsTrue(corpus.Ctx.Events[0].ContainsKey("timestamp"), "The recorded event should have had a timestamp key");
            Assert.IsTrue(corpus.Ctx.Events[0]["correlationId"] == DummyCorrelationId, "The recorded event should have had a correlationId key with the dummy value");

            // Test resolving a manifest not added to a folder, this should yield at least one error message in the recorder
            await manifest.CreateResolvedManifestAsync("new dummy", null);

            Assert.IsFalse(corpus.Ctx.Events.IsRecording, "Recording should be disabled at the end of API call");
            Assert.IsTrue(corpus.Ctx.Events.Count > 0, "There should have been at least one event recorded");
            Assert.IsTrue(corpus.Ctx.Events[0].ContainsKey("timestamp"), "The recorded event should have had a timestamp key");
            Assert.IsTrue(corpus.Ctx.Events[0]["correlationId"] == DummyCorrelationId, "The recorded event should have had a correlationId key with the dummy value");

            // Test resolving an entity without WRT doc, this should yield at least one error message in the recorder
            var entity2 = corpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, "MyEntity2");
            await entity2.CreateResolvedEntityAsync("MyEntity2-Resolved");

            Assert.IsFalse(corpus.Ctx.Events.IsRecording, "Recording should be disabled at the end of API call");
            Assert.IsTrue(corpus.Ctx.Events.Count > 0, "There should have been at least one event recorded");
            Assert.IsTrue(corpus.Ctx.Events[0].ContainsKey("timestamp"), "The recorded event should have had a timestamp key");
            Assert.IsTrue(corpus.Ctx.Events[0]["correlationId"] == DummyCorrelationId, "The recorded event should have had a correlationId key with the dummy value");

            // Test invoking FileStatusCheckAsync on the manifest, this should yield at least one error message in the recorder
            await manifest.FileStatusCheckAsync();

            Assert.IsFalse(corpus.Ctx.Events.IsRecording, "Recording should be disabled at the end of API call");
            Assert.IsTrue(corpus.Ctx.Events.Count > 0, "There should have been at least one event recorded");
            Assert.IsTrue(corpus.Ctx.Events[0].ContainsKey("timestamp"), "The recorded event should have had a timestamp key");
            Assert.IsTrue(corpus.Ctx.Events[0]["correlationId"] == DummyCorrelationId, "The recorded event should have had a correlationId key with the dummy value");

            // Repeat the same test but with status level 'None', no events should be recorded
            corpus.Ctx.ReportAtLevel = CdmStatusLevel.None;
            await entity2.CreateResolvedEntityAsync("MyEntity2-Resolved");

            Assert.IsFalse(corpus.Ctx.Events.IsRecording, "Recording should be disabled at the end of API call");
            Assert.IsTrue(corpus.Ctx.Events.Count == 0, "There should have been no events recorded when fetching object with correct path");
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Create a projection object with operations
        /// </summary>
        /// <param name="corpus"></param>
        /// <returns></returns>
        private CdmProjection CreateProjectionWithOperationCollection(CdmCorpusDefinition corpus, CdmObject owner)
        {
            CdmProjection projection = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            {
                projection.Source = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, "TestSource", simpleNameRef: true);
            }

            {
                // AddCountAttribute Operation
                CdmOperationAddCountAttribute addCountAttributeOp = new CdmOperationAddCountAttribute(corpus.Ctx)
                {
                    CountAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef)
                };
                projection.Operations.Add(addCountAttributeOp);

                // AddSupportingAttribute Operation
                CdmOperationAddSupportingAttribute addSupportingAttributesOp = new CdmOperationAddSupportingAttribute(corpus.Ctx)
                {
                    SupportingAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef)
                };
                projection.Operations.Add(addSupportingAttributesOp);

                // AddTypeAttribute Operation
                CdmOperationAddTypeAttribute addTypeAttributeOp = new CdmOperationAddTypeAttribute(corpus.Ctx)
                {
                    TypeAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef)
                };
                projection.Operations.Add(addTypeAttributeOp);

                // ExcludeAttributes Operation
                CdmOperationExcludeAttributes excludeAttributesOp = new CdmOperationExcludeAttributes(corpus.Ctx)
                {
                    ExcludeAttributes = new List <string>()
                };
                excludeAttributesOp.ExcludeAttributes.Add("testAttribute1");
                projection.Operations.Add(excludeAttributesOp);

                // ArrayExpansion Operation
                CdmOperationArrayExpansion arrayExpansionOp = new CdmOperationArrayExpansion(corpus.Ctx)
                {
                    StartOrdinal = 0,
                    EndOrdinal   = 1
                };
                projection.Operations.Add(arrayExpansionOp);

                // CombineAttributes Operation
                CdmOperationCombineAttributes combineAttributesOp = new CdmOperationCombineAttributes(corpus.Ctx)
                {
                    Take      = new List <string>(),
                    MergeInto = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef)
                };
                combineAttributesOp.Take.Add("testAttribute1");
                projection.Operations.Add(combineAttributesOp);

                // RenameAttributes Operation
                CdmOperationRenameAttributes renameAttributesOp = new CdmOperationRenameAttributes(corpus.Ctx)
                {
                    RenameFormat = "{m}"
                };
                projection.Operations.Add(renameAttributesOp);

                // ReplaceAsForeignKey Operation
                CdmOperationReplaceAsForeignKey replaceAsForeignKeyOp = new CdmOperationReplaceAsForeignKey(corpus.Ctx)
                {
                    Reference   = "testAttribute1",
                    ReplaceWith = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "testForeignKey", simpleNameRef: false)
                };
                projection.Operations.Add(replaceAsForeignKeyOp);

                // IncludeAttributes Operation
                CdmOperationIncludeAttributes includeAttributesOp = new CdmOperationIncludeAttributes(corpus.Ctx)
                {
                    IncludeAttributes = new List <string>()
                };
                includeAttributesOp.IncludeAttributes.Add("testAttribute1");
                projection.Operations.Add(includeAttributesOp);
            }

            return(projection);
        }
Ejemplo n.º 23
0
        private async Task CustomizeEntities(CdmCorpusDefinition cdmCorpus)
        {
            // Open the default manifest at the root, used later when done
            // This method turns relative corpus paths into absolute ones in case we are in some sub-folders and don't know it
            var manifest = await cdmCorpus.FetchObjectAsync <CdmManifestDefinition>("default.manifest.cdm.json");

            Console.WriteLine("Define new extension");

            // First we will make a new document right in the same folder as the manifest
            var docAbs = cdmCorpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, "MobileCareTeam.cdm.json");

            // Import the cdm description of the original so the symbols will resolve
            docAbs.Imports.Add("cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/CareTeam.cdm.json", null);

            // We will make a new trait to identify things that are known to be temporary, used later
            // In theory this would be defined somewhere central so it can be shared
            var traitTemp = docAbs.Definitions.Add(CdmObjectType.TraitDef, "means.temporary") as CdmTraitDefinition;

            // Extends the standard 'means' base trait
            traitTemp.ExtendsTrait = cdmCorpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, "means", true);
            // Add a parameter for the expected duration in days
            var param = cdmCorpus.MakeObject <CdmParameterDefinition>(CdmObjectType.ParameterDef, "estimatedDays");

            // By not using "true" on the last arg, this becomes an real reference object in the json. go look at the difference from "means" when this is done
            param.DataTypeRef  = cdmCorpus.MakeObject <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "integer");
            param.DefaultValue = "30";
            traitTemp.Parameters.Add(param);

            // Make an entity definition and add it to the list of definitions in the document.
            CdmEntityDefinition entAbs = docAbs.Definitions.Add(CdmObjectType.EntityDef, "MobileCareTeam") as CdmEntityDefinition;

            // This entity extends the standard
            // This function with 'true' will make a simple reference to the base
            entAbs.ExtendsEntity = cdmCorpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, "CareTeam", true);

            // and we will add an attribute
            CdmTypeAttributeDefinition attNew = cdmCorpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "currentCity");

            // The attribute is a type is 'City" this is one of the predefined semantic types in meanings.cdm.json
            attNew.DataType    = cdmCorpus.MakeObject <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "city", true);
            attNew.Description = "The current city where the mobile care team is working.";

            // also apply our fancy new 'temporary' trait. they stay in a city for 90 days on average
            CdmTraitReference tr = cdmCorpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, "means.temporary");

            tr.Arguments.Add("estimatedDays", "90");
            attNew.AppliedTraits.Add(tr);

            // Add attribute to the entity
            entAbs.Attributes.Add(attNew);

            // The entity abstract definition is done, add the document to the corpus in the root folder and then save that doc
            cdmCorpus.Storage.FetchRootFolder("local").Documents.Add(docAbs);

            // next step is to remove all of the guesswork out of decoding the entity shape by 'resolving' it to a relational by reference shape
            Console.WriteLine("Make a local 'resolved' copy");

            // Now resolve it
            // Made the entity and document have a different name to avoid conflicts in this folder
            var entFlat = await entAbs.CreateResolvedEntityAsync("LocalMobileCareTeam");

            // Now just add the pointer into our manifest.
            Console.WriteLine("Add to manifest");
            manifest.Entities.Add(entFlat);

            // This function will update all of the fileStatus times in the manifest
            // await manifest.RefreshAsync(null);

            // Save the manifest along with linked definition files.
            await manifest.SaveAsAsync("default-resolved.manifest.cdm.json", true);
        }
Ejemplo n.º 24
0
        public async Task TestConditionalProjUsingObjectModel()
        {
            CdmCorpusDefinition corpus = ProjectionTestUtils.GetLocalCorpus(testsSubpath, "TestConditionalProjUsingObjectModel");

            corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestConditionalProjUsingObjectModel")));
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection with a condition that states the operation should only execute when the resolution directive is 'referenceOnly'
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            projection.Condition = "referenceOnly==true";

            // Create an AddTypeAttribute operation
            CdmOperationAddTypeAttribute addTypeAttrOp = corpus.MakeObject <CdmOperationAddTypeAttribute>(CdmObjectType.OperationAddTypeAttributeDef);

            addTypeAttrOp.TypeAttribute          = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "testType");
            addTypeAttrOp.TypeAttribute.DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "entityName", true);
            projection.Operations.Add(addTypeAttrOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create an entity attribute that contains this projection and add this to the entity
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef;
            entity.Attributes.Add(entityAttribute);

            // Create resolution options with the 'referenceOnly' directive
            ResolveOptions resOpt = new ResolveOptions(entity.InDocument);

            resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                "referenceOnly"
            });

            // Resolve the entity with 'referenceOnly'
            CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Verify correctness of the resolved attributes after running the AddTypeAttribute operation
            // Original set of attributes: ["id", "name", "value", "date"]
            // Type attribute: "testType"
            Assert.AreEqual(5, resolvedEntityWithReferenceOnly.Attributes.Count);
            Assert.AreEqual("id", (resolvedEntityWithReferenceOnly.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (resolvedEntityWithReferenceOnly.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (resolvedEntityWithReferenceOnly.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (resolvedEntityWithReferenceOnly.Attributes[3] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("testType", (resolvedEntityWithReferenceOnly.Attributes[4] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("is.linkedEntity.name", resolvedEntityWithReferenceOnly.Attributes[4].AppliedTraits[4].NamedReference);

            // Now resolve the entity with the 'structured' directive
            resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                "structured"
            });
            CdmEntityDefinition resolvedEntityWithStructured = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Verify correctness of the resolved attributes after running the AddTypeAttribute operation
            // Original set of attributes: ["id", "name", "value", "date"]
            // No Type attribute added, condition was false
            Assert.AreEqual(4, resolvedEntityWithStructured.Attributes.Count);
            Assert.AreEqual("id", (resolvedEntityWithStructured.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (resolvedEntityWithStructured.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (resolvedEntityWithStructured.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (resolvedEntityWithStructured.Attributes[3] as CdmTypeAttributeDefinition).Name);
        }
Ejemplo n.º 25
0
        static async Task Main()
        {
            // Make a corpus, the corpus is the collection of all documents and folders created or discovered while navigating objects and paths
            var cdmCorpus = new CdmCorpusDefinition();

            Console.WriteLine("Configuring storage adapters");

            // Configure storage adapters to point at the target local manifest location and at the fake public standards
            var pathFromExeToExampleRoot = "../";

            cdmCorpus.Storage.Mount("local", new LocalAdapter(pathFromExeToExampleRoot + "output"));
            cdmCorpus.Storage.DefaultNamespace = "local"; // local is our default. so any paths that start out navigating without a device tag will assume local

            // Fake cdm, normaly use the github adapter
            // Mount it as the 'cdm' device, not the default so must use "cdm:/folder" to get there
            cdmCorpus.Storage.Mount("cdm", new LocalAdapter(pathFromExeToExampleRoot + "base-files"));

            // Example how to mount to the ADLS.
            // cdmCorpus.Storage.Mount("adls",
            //    new ADLSAdapter(
            // "<ACCOUNT-NAME>.dfs.core.windows.net", // Hostname.
            // "/<FILESYSTEM-NAME>", // Root.
            // "72f988bf-86f1-41af-91ab-2d7cd011db47",  // Tenant ID.
            // "<CLIENT-ID>",  // Client ID.
            // "<CLIENT-SECRET>" // Client secret.
            // ));

            Console.WriteLine("Creating placeholder manifest");
            // Make the temp manifest and add it to the root of the local documents in the corpus
            CdmManifestDefinition manifestAbstract = cdmCorpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "tempAbstract");

            // Add the temp manifest to the root of the local documents in the corpus
            var localRoot = cdmCorpus.Storage.FetchRootFolder("local");

            localRoot.Documents.Add(manifestAbstract, "TempAbstract.manifest.cdm.json");


            //READ CSV - OBSERVE SCHEMA: "entity, atribute, datatype" every row, no headers
            Console.WriteLine("Loading CDM definition file");
            List <string> entitylist    = new List <string>();
            List <string> attributelist = new List <string>();
            List <string> datatypelist  = new List <string>();

            using (var reader = new System.IO.StreamReader(@"../cdmdefinition.csv"))
            {
                while (!reader.EndOfStream)
                {
                    var line   = reader.ReadLine();
                    var values = line.Split(',');

                    entitylist.Add(values[0]);
                    attributelist.Add(values[1]);
                    datatypelist.Add(values[2]);
                }
            }

            // Create entities and add  attributes
            string entityname;
            CdmEntityDefinition entity;
            bool isnew = true;

            for (int i = 0; i < entitylist.Count; i++)
            {
                isnew      = true;
                entityname = entitylist[i];
                Console.WriteLine("Creating " + entityname + " entity");
                entity = cdmCorpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, entityname, false);
                while (i == 0 || entitylist[i] == entitylist[i - 1] || isnew)
                {
                    isnew = false;
                    var attribute = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, attributelist[i], "hasA", datatypelist[i]);
                    entity.Attributes.Add(attribute);
                    i++;
                    if (i == entitylist.Count)
                    {
                        break;
                    }
                }
                if (i != entitylist.Count)
                {
                    i--;
                }
                // Create the document which contains the entity
                var entitydoc = cdmCorpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{entityname}.cdm.json", false);
                // Add an import to the foundations doc so the traits about partitons will resolve nicely
                entitydoc.Imports.Add(FoundationJsonPath);
                entitydoc.Definitions.Add(entity);
                // Add the document to the root of the local documents in the corpus
                localRoot.Documents.Add(entitydoc, entitydoc.Name);
                // Add the entity to the manifest
                manifestAbstract.Entities.Add(entity);
            }

            //THIAGO - MANUAL BREAKDOWN BEFORE AUTOMATING

            /*var entityname = "FixedAssetMaster";
             * var entity = cdmCorpus.MakeObject<CdmEntityDefinition>(CdmObjectType.EntityDef, entityname, false);
             * var attribute1 = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, "Attribute1", "hasA", "string");
             * entity.Attributes.Add(attribute1);
             * var attribute2 = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, "Attribute2", "hasA", "string");
             * entity.Attributes.Add(attribute2);
             * // Create the document which contains the entity
             * var entitydoc = cdmCorpus.MakeObject<CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{entityname}.cdm.json", false);
             * // Add an import to the foundations doc so the traits about partitons will resolve nicely
             * entitydoc.Imports.Add(FoundationJsonPath);
             * entitydoc.Definitions.Add(entity);
             * // Add the document to the root of the local documents in the corpus
             * localRoot.Documents.Add(entitydoc, entitydoc.Name);
             * // Add the entity to the manifest
             * manifestAbstract.Entities.Add(entity);*/

            /*
             * // Create the simplest entity - CustomPerson
             * // Create the entity definition instance
             * var personEntity = cdmCorpus.MakeObject<CdmEntityDefinition>(CdmObjectType.EntityDef, CustomPersonEntityName, false);
             * // Add type attributes to the entity instance
             * var personAttributeId = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomPersonEntityName}Id", "identifiedBy", "entityId");
             * personEntity.Attributes.Add(personAttributeId);
             * var personAttributeName = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomPersonEntityName}Name", "hasA", "string");
             * personEntity.Attributes.Add(personAttributeName);
             * // Add properties to the entity instance
             * personEntity.DisplayName = CustomPersonEntityName;
             * personEntity.Version = "0.0.1";
             * personEntity.Description = "This is a custom entity created for the sample.";
             * // Create the document which contains the entity
             * var personEntityDoc = cdmCorpus.MakeObject<CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{CustomPersonEntityName}.cdm.json", false);
             * // Add an import to the foundations doc so the traits about partitons will resolve nicely
             * personEntityDoc.Imports.Add(FoundationJsonPath);
             * personEntityDoc.Definitions.Add(personEntity);
             * // Add the document to the root of the local documents in the corpus
             * localRoot.Documents.Add(personEntityDoc, personEntityDoc.Name);
             * // Add the entity to the manifest
             * manifestAbstract.Entities.Add(personEntity);
             *
             *
             * // Create an entity - CustomAccount which has a relationship with the entity CustomPerson
             * // Create the entity definition instance
             * var accountEntity = cdmCorpus.MakeObject<CdmEntityDefinition>(CdmObjectType.EntityDef, CustomAccountEntityName, false);
             * // Add type attributes to the entity instance
             * var accountAttributeId = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomAccountEntityName}Id", "identifiedBy", "entityId");
             * accountEntity.Attributes.Add(accountAttributeId);
             * var accountAttributeName = CreateEntityAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomAccountEntityName}Name", "hasA", "string");
             * accountEntity.Attributes.Add(accountAttributeName);
             * // Add properties to the entity instance
             * accountEntity.DisplayName = CustomAccountEntityName;
             * accountEntity.Version = "0.0.1";
             * accountEntity.Description = "This is a custom entity created for the sample.";
             * // In this sample, every account has one person who owns the account
             * // the relationship is actually an entity attribute
             * var attributeExplanation = "The owner of the account, which is a person.";
             * // You can all CreateSimpleAttributeForRelationshipBetweenTwoEntities() instead, but CreateAttributeForRelationshipBetweenTwoEntities() can show
             * // more details of how to use resolution guidance to customize your data
             * var accountOwnerAttribute = CreateAttributeForRelationshipBetweenTwoEntities(cdmCorpus, CustomPersonEntityName, "accountOwner", attributeExplanation);
             * accountEntity.Attributes.Add(accountOwnerAttribute);
             * // Create the document which contains the entity
             * var accountEntityDoc = cdmCorpus.MakeObject<CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{CustomAccountEntityName}.cdm.json", false);
             * // Add an import to the foundations doc so the traits about partitons will resolve nicely
             * accountEntityDoc.Imports.Add(FoundationJsonPath);
             * // the CustomAccount entity has a relationship with the CustomPerson entity, this relationship is defined from its attribute with traits,
             * // the import to the entity reference CustomPerson's doc is required
             * accountEntityDoc.Imports.Add($"{CustomPersonEntityName}.cdm.json");
             * accountEntityDoc.Definitions.Add(accountEntity);
             * // Add the document to the root of the local documents in the corpus
             * localRoot.Documents.Add(accountEntityDoc, accountEntityDoc.Name);
             * // Add the entity to the manifest
             * manifestAbstract.Entities.Add(accountEntity);
             *
             *
             * // Create an entity which extends "Account" from the standard, it contains everything that "Account" has
             * var extendedStandardAccountEntity = cdmCorpus.MakeObject<CdmEntityDefinition>(CdmObjectType.EntityDef, ExtendedStandardAccount, false);
             * // This function with 'true' will make a simple reference to the base
             * extendedStandardAccountEntity.ExtendsEntity = cdmCorpus.MakeObject<CdmEntityReference>(CdmObjectType.EntityRef, "Account", true);
             * var attrExplanation = "This is a simple custom account for this sample.";
             * // Add a relationship from it to the CustomAccount entity, and name the foreign key to SimpleCustomAccount
             * // You can all CreateSimpleAttributeForRelationshipBetweenTwoEntities() instead, but CreateAttributeForRelationshipBetweenTwoEntities() can show
             * // more details of how to use resolution guidance to customize your data
             * var simpleCustomAccountAttribute = CreateAttributeForRelationshipBetweenTwoEntities(cdmCorpus, CustomAccountEntityName, "SimpleCustomAccount", attrExplanation);
             * extendedStandardAccountEntity.Attributes.Add(simpleCustomAccountAttribute);
             * var extendedStandardAccountEntityDoc = cdmCorpus.MakeObject<CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{ExtendedStandardAccount}.cdm.json", false);
             * // Add an import to the foundations doc so the traits about partitons will resolve nicely
             * extendedStandardAccountEntityDoc.Imports.Add(FoundationJsonPath);
             * // The ExtendedAccount entity extends from the "Account" entity from standards, the import to the entity Account's doc is required
             * // it also has a relationship with the CustomAccount entity, the relationship defined from its from its attribute with traits, the import to the entity reference CustomAccount's doc is required
             * extendedStandardAccountEntityDoc.Imports.Add($"{SchemaDocsRoot}/Account.cdm.json");
             * extendedStandardAccountEntityDoc.Imports.Add($"{CustomAccountEntityName}.cdm.json");
             * // Add the document to the root of the local documents in the corpus
             * localRoot.Documents.Add(extendedStandardAccountEntityDoc, extendedStandardAccountEntityDoc.Name);
             * extendedStandardAccountEntityDoc.Definitions.Add(extendedStandardAccountEntity);
             * // Add the entity to the manifest
             * manifestAbstract.Entities.Add(extendedStandardAccountEntity);
             */

            // Create the resolved version of everything in the root folder too
            Console.WriteLine("Resolving the placeholder");
            var manifestResolved = await manifestAbstract.CreateResolvedManifestAsync("default", null);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            manifestResolved.Imports.Add(FoundationJsonPath);

            Console.WriteLine("Saving the documents");
            foreach (CdmEntityDeclarationDefinition eDef in manifestResolved.Entities)
            {
                // Get the entity being pointed at
                var localEDef = eDef;
                var entDef    = await cdmCorpus.FetchObjectAsync <CdmEntityDefinition>(localEDef.EntityPath, manifestResolved);

                // Make a fake partition, just to demo that
                var part = cdmCorpus.MakeObject <CdmDataPartitionDefinition>(CdmObjectType.DataPartitionDef, $"{entDef.EntityName}-data-description");
                localEDef.DataPartitions.Add(part);
                part.Explanation = "not real data, just for demo";
                // We have existing partition files for the custom entities, so we need to make the partition point to the file location
                part.Location = $"local:/{entDef.EntityName}/partition-data.csv";
                // Add trait to partition for csv params
                var csvTrait = part.ExhibitsTraits.Add("is.partition.format.CSV", false);
                csvTrait.Arguments.Add("columnHeaders", "true");
                csvTrait.Arguments.Add("delimiter", ",");
            }

            // We can save the documents as manifest.cdm.json format or model.json
            // Save as manifest.cdm.json
            await manifestResolved.SaveAsAsync($"{manifestResolved.ManifestName}.manifest.cdm.json", true);

            // Save as a model.json
            // await manifestResolved.SaveAsAsync("model.json", true);

            Console.WriteLine("Finished");
            Console.ReadKey();
        }
Ejemplo n.º 26
0
        private async Task SearchPartitionPattern(CdmCorpusDefinition cdmCorpus)
        {
            string sampleEntityName = "Account";

            Console.WriteLine("Make placeholder manifest");
            // Make the temp manifest and add it to the root of the local documents in the corpus
            CdmManifestDefinition manifestAbstract = cdmCorpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "tempAbstract");

            // Add the temp manifest to the root of the local documents in the corpus.
            var localRoot = cdmCorpus.Storage.FetchRootFolder("local");

            localRoot.Documents.Add(manifestAbstract, "tempAbstract.manifest.cdm.json");

            // Add an entity named Account from some public standards
            Console.WriteLine("Add an entity named Account from some public standards");
            var accountDeclarationDefinition = manifestAbstract.Entities.Add(sampleEntityName, "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Account.cdm.json/Account");

            // Create a data partition pattern
            var dataPartitionPattern = CreatePartitionPatternDefinition(cdmCorpus, "sampleDataPartitionPattern");

            dataPartitionPattern.Explanation = "/ capture 4 digits / capture a word / capture one or more digits after the word cohort but before .csv";
            Console.WriteLine($"    Assign regular expression of the data partition pattern to: {dataPartitionPattern.RegularExpression}");
            Console.WriteLine($"    Assign root location of the data partition pattern to: {dataPartitionPattern.RootLocation}");

            // Add the data partition pattern we just created to the entity data partition pattern collection
            accountDeclarationDefinition.DataPartitionPatterns.Add(dataPartitionPattern);

            // Create incremental partition patterns
            var upsertIncrementalPartitionPattern = CreatePartitionPatternDefinition(cdmCorpus, "UpsertPattern", true, true);

            AddIncrementalPartitionTrait(upsertIncrementalPartitionPattern, CdmIncrementalPartitionType.Upsert);
            Console.WriteLine($"\n    Assign regular expression of the first incremental partition pattern to: {upsertIncrementalPartitionPattern.RegularExpression}");
            Console.WriteLine($"    Assign root location of the first incremental partition pattern to: {upsertIncrementalPartitionPattern.RootLocation}");

            var deleteIncrementalPartitionPattern = CreatePartitionPatternDefinition(cdmCorpus, "DeletePattern", true);

            AddIncrementalPartitionTrait(deleteIncrementalPartitionPattern, CdmIncrementalPartitionType.Delete, "FullDataPattern");
            Console.WriteLine($"\n    Assign regular expression of the second incremental partition pattern to: {deleteIncrementalPartitionPattern.RegularExpression}");
            Console.WriteLine($"    Assign root location of the second incremental partition pattern to: {deleteIncrementalPartitionPattern.RootLocation}");

            // Add the incremental partition patterns we just created to the entity increment partition pattern collection
            accountDeclarationDefinition.IncrementalPartitionPatterns.Add(upsertIncrementalPartitionPattern);
            accountDeclarationDefinition.IncrementalPartitionPatterns.Add(deleteIncrementalPartitionPattern);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            manifestAbstract.Imports.Add("cdm:/foundations.cdm.json");

            // Calling FileStatusCheckAsync to pick up the all data partition files which names match the data partition pattern,
            // and add them to the entity in the manifest
            await manifestAbstract.FileStatusCheckAsync(PartitionFileStatusCheckType.FullAndIncremental);

            // List all data partition locations.
            Console.WriteLine($"\nlist of all data partition locations for the entity Account matches the data partition pattern:");

            foreach (CdmDataPartitionDefinition dataPartition in accountDeclarationDefinition.DataPartitions)
            {
                Console.WriteLine($"    {dataPartition.Location}");
            }

            // List all incremental partition locations.
            Console.WriteLine($"\nlist of all incremental partition locations for the entity Account matches the incremental partition pattern:");

            foreach (CdmDataPartitionDefinition incrementalPartition in accountDeclarationDefinition.IncrementalPartitions)
            {
                Console.WriteLine($"    {incrementalPartition.Location}");
            }

            Console.WriteLine("Resolve the manifest");
            var manifestResolved = await manifestAbstract.CreateResolvedManifestAsync("default", null);

            await manifestResolved.SaveAsAsync($"{manifestResolved.ManifestName}.manifest.cdm.json", true);

            // You can save the doc as a model.json format as an option
            // await manifestResolved.SaveAsAsync("model.json", true);
        }
        static async Task Main(string[] args)
        {
            var pathFromExeToExampleRoot = "../../../../../../";

            // ------------------------------------------------------------------------------------------------------------
            // Instantiate corpus and set up the default namespace to be local

            var cdmCorpus = new CdmCorpusDefinition();

            cdmCorpus.Storage.DefaultNamespace = "local";

            // ------------------------------------------------------------------------------------------------------------
            // Set up adapters for managing access to different files-system locations

            // Fake cdm, normaly use the github adapter
            // Mount it as the 'cdm' device, not the default so must use "cdm:/folder" to get there
            cdmCorpus.Storage.Mount("cdm", new LocalAdapter(pathFromExeToExampleRoot + "example-public-standards"));

            cdmCorpus.Storage.Mount("local", new LocalAdapter(modelJsonRoot));

            // Example how to mount to the ADLS - make sure the hostname and root entered here are also changed
            // in the example.model.json file we load in the next section
            cdmCorpus.Storage.Mount("adls",
                                    new ADLSAdapter(
                                        "<ACCOUNT-NAME>.dfs.core.windows.net",  // Hostname.
                                        "/<FILESYSTEM-NAME>",                   // Root.
                                        "72f988bf-86f1-41af-91ab-2d7cd011db47", // Tenant ID.
                                        "<CLIENT-ID>",                          // Client ID.
                                        "<CLIENT-SECRET>"                       // Client secret.
                                        ));

            // ------------------------------------------------------------------------------------------------------------
            // Load a model.json file from local FS

            var manifest = await cdmCorpus.FetchObjectAsync <CdmManifestDefinition>("local:/model.json");

            // ------------------------------------------------------------------------------------------------------------
            // Explore entities and partitions defined in the model

            Console.WriteLine("Listing entity declarations:");
            foreach (CdmEntityDeclarationDefinition decl in manifest.Entities)
            {
                Console.WriteLine("  " + decl.EntityName);

                // TODO: This can be rewritten in a different way since data partition gives null for referenced entities, suggestions are welcome.
                if (decl.ObjectType == CdmObjectType.LocalEntityDeclarationDef)
                {
                    foreach (CdmDataPartitionDefinition dataPart in decl.DataPartitions)
                    {
                        Console.WriteLine("    " + dataPart.Location);
                    }
                }
            }

            // ------------------------------------------------------------------------------------------------------------
            // Make changes to the model

            // Create a new document where the new entity's definition will be stored
            var newEntityDoc = cdmCorpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, "NewEntity.cdm.json", false);

            newEntityDoc.Imports.Add("cdm:/foundations.cdm.json");
            cdmCorpus.Storage.FetchRootFolder("local").Documents.Add(newEntityDoc);

            var newEntity = newEntityDoc.Definitions.Add(CdmObjectType.EntityDef, "NewEntity") as CdmEntityDefinition;

            // Define new string attribute and add it to the entity definition
            var newAttribute = cdmCorpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "NewAttribute", false);

            newAttribute.DataFormat = CdmDataFormat.String;
            newEntity.Attributes.Add(newAttribute);

            // Call will create EntityDeclarationDefinition based on entity definition and add it to manifest.Entities
            var newEntityDecl = manifest.Entities.Add(newEntity);

            // Define a partition and add it to the local declaration
            var newPartition = cdmCorpus.MakeObject <CdmDataPartitionDefinition>(CdmObjectType.DataPartitionDef, "NewPartition", false);

            newPartition.Location = "adls:/NewPartition.csv";
            newEntityDecl.DataPartitions.Add(newPartition);

            // ------------------------------------------------------------------------------------------------------------
            // Save the file to ADLSg2 - we achieve that by adding the manifest to the root folder of
            // the ADLS file-system and performing a save on the manifest

            CdmFolderDefinition adlsFolder = cdmCorpus.Storage.FetchRootFolder("adls");

            adlsFolder.Documents.Add(manifest);
            await manifest.SaveAsAsync("model.json", true);
        }
Ejemplo n.º 28
0
        static async Task Main(string[] args)
        {
            // Make a corpus, the corpus is the collection of all documents and folders created or discovered while navigating objects and paths
            var cdmCorpus = new CdmCorpusDefinition();

            // set callback to receive error and warning logs.
            cdmCorpus.SetEventCallback(new EventCallback
            {
                Invoke = (level, message) =>
                {
                    Console.WriteLine(message);
                }
            }, CdmStatusLevel.Warning);

            Console.WriteLine("Configure storage adapters");

            // Configure storage adapters to point at the target local manifest location and at the fake public standards
            string pathFromExeToExampleRoot = "../../../../../../../";
            string sampleEntityName         = "Account";

            // Mount it as a local adapter.
            cdmCorpus.Storage.Mount("local", new LocalAdapter(pathFromExeToExampleRoot + "7-search-partition-pattern/sample-data"));
            cdmCorpus.Storage.DefaultNamespace = "local"; // local is our default. so any paths that start out navigating without a device tag will assume local

            // Fake cdm, normaly use the CDM Standards adapter
            // Mount it as the 'cdm' adapter, not the default so must use "cdm:/folder" to get there
            cdmCorpus.Storage.Mount("cdm", new LocalAdapter(pathFromExeToExampleRoot + "example-public-standards"));

            // Example how to mount to the ADLS.
            // cdmCorpus.Storage.Mount("adls",
            //    new ADLSAdapter(
            // "<ACCOUNT-NAME>.dfs.core.windows.net", // Hostname.
            // "/<FILESYSTEM-NAME>", // Root.
            // "72f988bf-86f1-41af-91ab-2d7cd011db47",  // Tenant ID.
            // "<CLIENT-ID>",  // Client ID.
            // "<CLIENT-SECRET>" // Client secret.
            // ));

            Console.WriteLine("Make placeholder manifest");
            // Make the temp manifest and add it to the root of the local documents in the corpus
            CdmManifestDefinition manifestAbstract = cdmCorpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "tempAbstract");

            // Add the temp manifest to the root of the local documents in the corpus.
            var localRoot = cdmCorpus.Storage.FetchRootFolder("local");

            localRoot.Documents.Add(manifestAbstract, "tempAbstract.manifest.cdm.json");

            // Add an entity named Account from some public standards
            Console.WriteLine("Add an entity named Account from some public standards");
            var accountDeclarationDefinition = manifestAbstract.Entities.Add(sampleEntityName, "cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/Account.cdm.json/Account");

            // Create a data partition pattern
            var dataPartitionPattern = CreatePartitionPatternDefinition(cdmCorpus, "sampleDataPartitionPattern");

            dataPartitionPattern.Explanation = "/ capture 4 digits / capture a word / capture one or more digits after the word cohort but before .csv";
            Console.WriteLine($"    Assign regular expression of the data partition pattern to: {dataPartitionPattern.RegularExpression}");
            Console.WriteLine($"    Assign root location of the data partition pattern to: {dataPartitionPattern.RootLocation}");

            // Add the data partition pattern we just created to the entity data partition pattern collection
            accountDeclarationDefinition.DataPartitionPatterns.Add(dataPartitionPattern);

            // Create incremental partition patterns
            var upsertIncrementalPartitionPattern = CreatePartitionPatternDefinition(cdmCorpus, "UpsertPattern", true, true);

            AddIncrementalPartitionTrait(upsertIncrementalPartitionPattern, CdmIncrementalPartitionType.Upsert);
            Console.WriteLine($"\n    Assign regular expression of the first incremental partition pattern to: {upsertIncrementalPartitionPattern.RegularExpression}");
            Console.WriteLine($"    Assign root location of the first incremental partition pattern to: {upsertIncrementalPartitionPattern.RootLocation}");

            var deleteIncrementalPartitionPattern = CreatePartitionPatternDefinition(cdmCorpus, "DeletePattern", true);

            AddIncrementalPartitionTrait(deleteIncrementalPartitionPattern, CdmIncrementalPartitionType.Delete, "FullDataPattern");
            Console.WriteLine($"\n    Assign regular expression of the second incremental partition pattern to: {deleteIncrementalPartitionPattern.RegularExpression}");
            Console.WriteLine($"    Assign root location of the second incremental partition pattern to: {deleteIncrementalPartitionPattern.RootLocation}");

            // Add the incremental partition patterns we just created to the entity increment partition pattern collection
            accountDeclarationDefinition.IncrementalPartitionPatterns.Add(upsertIncrementalPartitionPattern);
            accountDeclarationDefinition.IncrementalPartitionPatterns.Add(deleteIncrementalPartitionPattern);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            manifestAbstract.Imports.Add("cdm:/foundations.cdm.json");

            // Calling FileStatusCheckAsync to pick up the all data partition files which names match the data partition pattern,
            // and add them to the entity in the manifest
            await manifestAbstract.FileStatusCheckAsync(PartitionFileStatusCheckType.FullAndIncremental);

            // List all data partition locations.
            Console.WriteLine($"\nlist of all data partition locations for the entity Account matches the data partition pattern:");

            foreach (CdmDataPartitionDefinition dataPartition in accountDeclarationDefinition.DataPartitions)
            {
                Console.WriteLine($"    {dataPartition.Location}");
            }

            // List all incremental partition locations.
            Console.WriteLine($"\nlist of all incremental partition locations for the entity Account matches the incremental partition pattern:");

            foreach (CdmDataPartitionDefinition incrementalPartition in accountDeclarationDefinition.IncrementalPartitions)
            {
                Console.WriteLine($"    {incrementalPartition.Location}");
            }

            Console.WriteLine("Resolve the manifest");
            var manifestResolved = await manifestAbstract.CreateResolvedManifestAsync("default", null);

            await manifestResolved.SaveAsAsync($"{manifestResolved.ManifestName}.manifest.cdm.json", true);

            // You can save the doc as a model.json format as an option
            // await manifestResolved.SaveAsAsync("model.json", true);
        }
Ejemplo n.º 29
0
        static async Task Main(string[] args)
        {
            // Make a corpus, the corpus is the collection of all documents and folders created or discovered while navigating objects and paths
            var cdmCorpus = new CdmCorpusDefinition();

            Console.WriteLine("Configure storage adapters");

            // Configure storage adapters to point at the target local manifest location and at the fake public standards
            string pathFromExeToExampleRoot = "../../../../../../";

            // Mount is as a local device.
            cdmCorpus.Storage.Mount("local", new LocalAdapter(pathFromExeToExampleRoot + "3-customize-entities"));
            cdmCorpus.Storage.DefaultNamespace = "local"; // local is our default. so any paths that start out navigating without a device tag will assume local

            // Mount it as the 'cdm' device, not the default so must use "cdm:/folder" to get there
            cdmCorpus.Storage.Mount("cdm", new LocalAdapter(pathFromExeToExampleRoot + "example-public-standards"));

            // Example how to mount to the ADLS.
            // cdmCorpus.Storage.Mount("adls",
            //    new ADLSAdapter(
            // "<ACCOUNT-NAME>.dfs.core.windows.net", // Hostname.
            // "/<FILESYSTEM-NAME>", // Root.
            // "72f988bf-86f1-41af-91ab-2d7cd011db47",  // Tenant ID.
            // "<CLIENT-ID>",  // Client ID.
            // "<CLIENT-SECRET>" // Client secret.
            // ));

            // Open the default manifest at the root, used later when done
            // This method turns relative corpus paths into absolute ones in case we are in some sub-folders and don't know it
            var manifest = await cdmCorpus.FetchObjectAsync <CdmManifestDefinition>("default.folio.cdm.json");

            Console.WriteLine("Define new extension");

            // First we will make a new document right in the same folder as the manifest
            var docAbs = cdmCorpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, "MobileCareTeam.cdm.json");

            // Import the cdm description of the original so the symbols will resolve
            docAbs.Imports.Add("cdm:/core/applicationCommon/foundationCommon/crmCommon/accelerators/healthCare/electronicMedicalRecords/CareTeam.cdm.json", null);

            // We will make a new trait to identify things that are known to be temporary, used later
            // In theory this would be defined somewhere central so it can be shared
            var traitTemp = docAbs.Definitions.Add(CdmObjectType.TraitDef, "means.temporary") as CdmTraitDefinition;

            // Extends the standard 'means' base trait
            traitTemp.ExtendsTrait = cdmCorpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, "means", true);
            // Add a parameter for the expected duration in days
            var param = cdmCorpus.MakeObject <CdmParameterDefinition>(CdmObjectType.ParameterDef, "estimatedDays");

            // By not using "true" on the last arg, this becomes an real reference object in the json. go look at the difference from "means" when this is done
            param.DataTypeRef  = cdmCorpus.MakeObject <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "integer");
            param.DefaultValue = "30";
            traitTemp.Parameters.Add(param);

            // Make an entity definition and add it to the list of definitions in the document.
            CdmEntityDefinition entAbs = docAbs.Definitions.Add(CdmObjectType.EntityDef, "MobileCareTeam") as CdmEntityDefinition;

            // This entity extends the standard
            // This function with 'true' will make a simple reference to the base
            entAbs.ExtendsEntity = cdmCorpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, "CareTeam", true);

            // and we will add an attribute
            CdmTypeAttributeDefinition attNew = cdmCorpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "currentCity");

            // The attribute is a type is 'City" this is one of the predefined semantic types in meanings.cdm.json
            attNew.DataType    = cdmCorpus.MakeObject <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "city", true);
            attNew.Description = "The current city where the mobile care team is working";

            // also apply our fancy new 'temporary' trait. they stay in a city for 90 days on average
            CdmTraitReference tr = cdmCorpus.MakeObject <CdmTraitReference>(CdmObjectType.TraitRef, "means.temporary");

            tr.Arguments.Add("estimatedDays", "90");
            attNew.AppliedTraits.Add(tr);

            // Add attribute to the entity
            entAbs.Attributes.Add(attNew);

            // The entity abstract definition is done, add the document to the corpus in the root folder and then save that doc
            cdmCorpus.Storage.FetchRootFolder("local").Documents.Add(docAbs);

            // next step is to remove all of the guesswork out of decoding the entity shape by 'resolving' it to a relational by reference shape
            Console.WriteLine("Make a local 'resolved' copy");

            // Now resolve it
            // Made the entity and document have a different name to avoid conflicts in this folder
            var entFlat = await entAbs.CreateResolvedEntityAsync("LocalMobileCareTeam");

            // Now just add the pointer into our manifest.
            Console.WriteLine("Add to manifest");
            manifest.Entities.Add(entFlat);

            // This function will update all of the fileStatus times in the manifest
            // await manifest.RefreshFileStatus();

            // Save the manifest along with linked definition files
            await manifest.SaveAsAsync("default.manifest.cdm.json", true);
        }
Ejemplo n.º 30
0
        private async Task CreateNetNewEntities(CdmCorpusDefinition cdmCorpus)
        {
            Console.WriteLine("Make placeholder manifest");
            // Make the temp manifest and add it to the root of the local documents in the corpus
            CdmManifestDefinition manifestAbstract = cdmCorpus.MakeObject <CdmManifestDefinition>(CdmObjectType.ManifestDef, "tempAbstract");

            // Add the temp manifest to the root of the local adapter in the corpus
            var localRoot = cdmCorpus.Storage.FetchRootFolder("local");

            localRoot.Documents.Add(manifestAbstract, "TempAbstract.manifest.cdm.json");

            // Create two entities from scratch, and add some attributes, traits, properties, and relationships in between
            Console.WriteLine("Create net new entities");


            // Create the simplest entity - CustomPerson
            // Create the entity definition instance
            var personEntity = cdmCorpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, CustomPersonEntityName, false);
            // Add type attributes to the entity instance
            // Both purpose "identifiedBy" and data type "entityId" are defined in public standards on the document /samples/example-public-standards/primitives.cdm.json
            var personAttributeId = CreateTypeAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomPersonEntityName}Id", "identifiedBy", "entityId");

            personEntity.Attributes.Add(personAttributeId);
            // Both purpose "hasA" and data type "name" are defined in public standards
            // The purpose "hasA" is from /samples/example-public-standards/primitives.cdm.json
            // The data type "name" is from /samples/example-public-standards/meanings.identity.cdm.json
            var personAttributeName = CreateTypeAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomPersonEntityName}Name", "hasA", "name");

            personEntity.Attributes.Add(personAttributeName);
            // Add properties to the entity instance
            personEntity.DisplayName = CustomPersonEntityName;
            personEntity.Version     = "0.0.1";
            personEntity.Description = "This is a custom entity created for the sample.";
            // Create the document which contains the entity
            var personEntityDoc = cdmCorpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{CustomPersonEntityName}.cdm.json", false);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            personEntityDoc.Imports.Add(FoundationJsonPath);
            personEntityDoc.Definitions.Add(personEntity);
            // Add the document to the root of the local documents in the corpus
            localRoot.Documents.Add(personEntityDoc, personEntityDoc.Name);
            // Add the entity to the manifest
            manifestAbstract.Entities.Add(personEntity);


            // Create an entity - CustomAccount which has a relationship with the entity CustomPerson
            // Create the entity definition instance
            var accountEntity = cdmCorpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, CustomAccountEntityName, false);
            // Add type attributes to the entity instance
            var accountAttributeId = CreateTypeAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomAccountEntityName}Id", "identifiedBy", "entityId");

            accountEntity.Attributes.Add(accountAttributeId);
            var accountAttributeName = CreateTypeAttributeWithPurposeAndDataType(cdmCorpus, $"{CustomAccountEntityName}Name", "hasA", "name");

            accountEntity.Attributes.Add(accountAttributeName);
            // Add properties to the entity instance
            accountEntity.DisplayName = CustomAccountEntityName;
            accountEntity.Version     = "0.0.1";
            accountEntity.Description = "This is a custom entity created for the sample.";
            // In this sample, every account has one person who owns the account
            // the relationship is actually an entity attribute
            var attributeExplanation = "The owner of the account, which is a person.";
            // You can call CreateSimpleAttributeForRelationshipBetweenTwoEntities() instead, but CreateEntityAttributeForRelationshipBetweenTwoEntities() can show
            // more details of how to use resolution guidance to customize your data
            var accountOwnerAttribute = CreateEntityAttributeForRelationshipBetweenTwoEntities(cdmCorpus, CustomPersonEntityName, "accountOwner", attributeExplanation);

            accountEntity.Attributes.Add(accountOwnerAttribute);
            // Create the document which contains the entity
            var accountEntityDoc = cdmCorpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{CustomAccountEntityName}.cdm.json", false);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            accountEntityDoc.Imports.Add(FoundationJsonPath);
            // The CustomAccount entity has a relationship with the CustomPerson entity, this relationship is defined from its attribute with traits,
            // the import to the entity reference CustomPerson's doc is required
            accountEntityDoc.Imports.Add($"{CustomPersonEntityName}.cdm.json");
            accountEntityDoc.Definitions.Add(accountEntity);
            // Add the document to the root of the local documents in the corpus
            localRoot.Documents.Add(accountEntityDoc, accountEntityDoc.Name);
            // Add the entity to the manifest
            manifestAbstract.Entities.Add(accountEntity);

            // Create an entity which extends "Account" from the standard, it contains everything that "Account" has
            var extendedStandardAccountEntity = cdmCorpus.MakeObject <CdmEntityDefinition>(CdmObjectType.EntityDef, ExtendedStandardAccount, false);

            // This function with 'true' will make a simple reference to the base
            extendedStandardAccountEntity.ExtendsEntity = cdmCorpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, "Account", true);
            var attrExplanation = "This is a simple custom account for this sample.";
            // Add a relationship from it to the CustomAccount entity, and name the foreign key to SimpleCustomAccount
            // You can also call CreateEntityAttributeForRelationshipBetweenTwoEntities() instead like above
            var simpleCustomAccountAttribute = CreateSimpleEntityAttributeForRelationshipBetweenTwoEntities(cdmCorpus, CustomAccountEntityName, "SimpleCustomAccount", attrExplanation);

            extendedStandardAccountEntity.Attributes.Add(simpleCustomAccountAttribute);
            var extendedStandardAccountEntityDoc = cdmCorpus.MakeObject <CdmDocumentDefinition>(CdmObjectType.DocumentDef, $"{ExtendedStandardAccount}.cdm.json", false);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            extendedStandardAccountEntityDoc.Imports.Add(FoundationJsonPath);
            // The ExtendedAccount entity extends from the "Account" entity from standards, the import to the entity Account's doc is required
            // it also has a relationship with the CustomAccount entity, the relationship defined from its from its attribute with traits, the import to the entity reference CustomAccount's doc is required
            extendedStandardAccountEntityDoc.Imports.Add($"{SchemaDocsRoot}/Account.cdm.json");
            extendedStandardAccountEntityDoc.Imports.Add($"{CustomAccountEntityName}.cdm.json");
            // Add the document to the root of the local documents in the corpus
            localRoot.Documents.Add(extendedStandardAccountEntityDoc, extendedStandardAccountEntityDoc.Name);
            extendedStandardAccountEntityDoc.Definitions.Add(extendedStandardAccountEntity);
            // Add the entity to the manifest
            manifestAbstract.Entities.Add(extendedStandardAccountEntity);

            // Create the resolved version of everything in the root folder too
            Console.WriteLine("Resolve the placeholder");
            var manifestResolved = await manifestAbstract.CreateResolvedManifestAsync("default", null);

            // Add an import to the foundations doc so the traits about partitons will resolve nicely
            manifestResolved.Imports.Add(FoundationJsonPath);

            Console.WriteLine("Save the documents");

            // We can save the documents as manifest.cdm.json format or model.json
            // Save as manifest.cdm.json
            await manifestResolved.SaveAsAsync($"{manifestResolved.ManifestName}.manifest.cdm.json", true);

            // Save as a model.json
            // await manifestResolved.SaveAsAsync("model.json", true);
        }