/* * JBoss, Home of Professional Open Source. * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. */ package org.teiid.translator.odata4; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Properties; import org.apache.olingo.client.api.edm.xml.DataServices; import org.apache.olingo.client.api.edm.xml.XMLMetadata; import org.apache.olingo.client.core.edm.ClientCsdlXMLMetadata; import org.apache.olingo.client.core.edm.xml.ClientCsdlEdmx; import org.apache.olingo.client.core.serialization.ClientODataDeserializerImpl; import org.apache.olingo.commons.api.edm.EdmComplexType; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmNavigationProperty; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.edm.EdmReferentialConstraint; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.edm.provider.CsdlAction; import org.apache.olingo.commons.api.edm.provider.CsdlActionImport; import org.apache.olingo.commons.api.edm.provider.CsdlComplexType; import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer; import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet; import org.apache.olingo.commons.api.edm.provider.CsdlEntityType; import org.apache.olingo.commons.api.edm.provider.CsdlFunction; import org.apache.olingo.commons.api.edm.provider.CsdlFunctionImport; import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty; import org.apache.olingo.commons.api.edm.provider.CsdlNavigationPropertyBinding; import org.apache.olingo.commons.api.edm.provider.CsdlParameter; import org.apache.olingo.commons.api.edm.provider.CsdlProperty; import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef; import org.apache.olingo.commons.api.edm.provider.CsdlReferentialConstraint; import org.apache.olingo.commons.api.edm.provider.CsdlReturnType; import org.apache.olingo.commons.api.edm.provider.CsdlSchema; import org.apache.olingo.commons.api.format.ContentType; import org.junit.Test; import org.teiid.core.util.UnitTestUtil; import org.teiid.metadata.BaseColumn.NullType; import org.teiid.metadata.Column; import org.teiid.metadata.ColumnSet; import org.teiid.metadata.ForeignKey; import org.teiid.metadata.KeyRecord; import org.teiid.metadata.ProcedureParameter; import org.teiid.metadata.KeyRecord.Type; import org.teiid.metadata.MetadataFactory; import org.teiid.metadata.Procedure; import org.teiid.metadata.Table; import org.teiid.query.function.FunctionTree; import org.teiid.query.function.UDFSource; import org.teiid.query.metadata.DDLStringVisitor; import org.teiid.query.metadata.MetadataValidator; import org.teiid.query.metadata.SystemMetadata; import org.teiid.query.metadata.TransformationMetadata; import org.teiid.query.parser.QueryParser; import org.teiid.query.unittest.RealMetadataFactory; import org.teiid.query.validator.ValidatorReport; import org.teiid.translator.TranslatorException; import org.teiid.translator.WSConnection; import org.teiid.translator.odata4.ODataExecutionFactory; import org.teiid.translator.odata4.ODataMetadataProcessor; import org.teiid.translator.odata4.ODataMetadataProcessor.ODataType; @SuppressWarnings({"nls", "unused"}) public class TestODataMetadataProcessor { private ODataExecutionFactory translator; public static TransformationMetadata getTransformationMetadata(MetadataFactory mf, ODataExecutionFactory ef) throws Exception { TransformationMetadata metadata = RealMetadataFactory.createTransformationMetadata(mf.asMetadataStore(), "trippin", new FunctionTree("foo", new UDFSource(ef.getPushDownFunctions()))); ValidatorReport report = new MetadataValidator().validate(metadata.getVdbMetaData(), metadata.getMetadataStore()); if (report.hasItems()) { throw new RuntimeException(report.getFailureMessage()); } return metadata; } static MetadataFactory tripPinMetadata() throws TranslatorException { ODataMetadataProcessor processor = new ODataMetadataProcessor() { protected XMLMetadata getSchema(WSConnection conn) throws TranslatorException { try { ClientODataDeserializerImpl deserializer = new ClientODataDeserializerImpl( false, ContentType.APPLICATION_XML); XMLMetadata metadata = deserializer.toMetadata( new FileInputStream(UnitTestUtil.getTestDataFile("trippin.xml"))); return metadata; } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } }; Properties props = new Properties(); props.setProperty("schemaNamespace", "Microsoft.OData.SampleService.Models.TripPin"); MetadataFactory mf = new MetadataFactory("vdb", 1, "trippin", SystemMetadata.getInstance().getRuntimeTypeMap(), props, null); processor.process(mf, null); // String ddl = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); // System.out.println(ddl); return mf; } @Test public void testSchema() throws Exception { translator = new ODataExecutionFactory(); translator.start(); MetadataFactory mf = tripPinMetadata(); TransformationMetadata metadata = getTransformationMetadata(mf, this.translator); String ddl = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); //System.out.println(ddl); MetadataFactory mf2 = new MetadataFactory("vdb", 1, "northwind", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); QueryParser.getQueryParser().parseDDL(mf2, ddl); Procedure p = mf.getSchema().getProcedure("ResetDataSource"); assertNotNull(p); assertEquals(0, p.getParameters().size()); } static CsdlProperty createProperty(String name, EdmPrimitiveTypeKind type) { return new CsdlProperty().setName(name).setType(type.getFullQualifiedName()); } static CsdlParameter createParameter(String name, EdmPrimitiveTypeKind type) { return new CsdlParameter().setName(name).setType(type.getFullQualifiedName()); } static XMLMetadata buildXmlMetadata(Object... schemaElements) { final CsdlSchema schema = new CsdlSchema(); schema.setNamespace("namespace"); schema.setEntityContainer(new CsdlEntityContainer()); ArrayList<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>(); ArrayList<CsdlEntityType> entityTypes = new ArrayList<CsdlEntityType>(); ArrayList<CsdlComplexType> complexTypes = new ArrayList<CsdlComplexType>(); ArrayList<CsdlFunctionImport> functionImports = new ArrayList<CsdlFunctionImport>(); ArrayList<CsdlFunction> functions = new ArrayList<CsdlFunction>(); ArrayList<CsdlActionImport> actionImports = new ArrayList<CsdlActionImport>(); ArrayList<CsdlAction> actions = new ArrayList<CsdlAction>(); for (Object obj:schemaElements) { if (obj instanceof CsdlEntitySet) { entitySets.add((CsdlEntitySet)obj); } else if (obj instanceof CsdlEntityType) { entityTypes.add((CsdlEntityType)obj); } else if (obj instanceof CsdlComplexType) { complexTypes.add((CsdlComplexType)obj); } else if (obj instanceof CsdlFunctionImport) { functionImports.add((CsdlFunctionImport)obj); } else if (obj instanceof CsdlFunction) { functions.add((CsdlFunction)obj); } else if (obj instanceof CsdlActionImport) { actionImports.add((CsdlActionImport)obj); } else if (obj instanceof CsdlAction) { actions.add((CsdlAction)obj); } } schema.setEntityTypes(entityTypes); schema.setComplexTypes(complexTypes); schema.setActions(actions); schema.setFunctions(functions); schema.getEntityContainer().setEntitySets(entitySets); schema.getEntityContainer().setFunctionImports(functionImports); schema.getEntityContainer().setActionImports(actionImports); ClientCsdlEdmx edmx = new ClientCsdlEdmx(); edmx.setVersion("1.0"); edmx.setDataServices(new DataServices() { @Override public List<CsdlSchema> getSchemas() { return Arrays.asList(schema); } @Override public String getMaxDataServiceVersion() { return "4.0"; } @Override public String getDataServiceVersion() { return "4.0"; } }); return new ClientCsdlXMLMetadata(edmx); } static CsdlEntitySet createES(String name, String entityType) { CsdlEntitySet es = new CsdlEntitySet(); es.setName(name); es.setType(new FullQualifiedName(entityType)); return es; } @Test public void testEnititySet() throws Exception { ODataMetadataProcessor processor = new ODataMetadataProcessor(); MetadataFactory mf = new MetadataFactory("vdb", 1, "trippin", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>(); properties.add(createProperty("name", EdmPrimitiveTypeKind.String).setMaxLength(25).setNullable(false)); properties.add(createProperty("dob", EdmPrimitiveTypeKind.DateTimeOffset).setNullable(true)); properties.add(createProperty("ssn", EdmPrimitiveTypeKind.Int64).setNullable(false)); CsdlEntityType entityType = new CsdlEntityType(); entityType.setName("Person"); entityType.setProperties(properties); entityType.setKey(Arrays.asList(new CsdlPropertyRef().setName("ssn"))); CsdlEntitySet es = createES("Persons", "namespace.Person"); XMLMetadata metadata = buildXmlMetadata(es, entityType); processor.getMetadata(mf, metadata); assertNotNull(mf.getSchema().getTable("Persons")); Table person = mf.getSchema().getTable("Persons"); assertEquals(3, person.getColumns().size()); assertNotNull(person.getColumnByName("name")); assertNotNull(person.getColumnByName("dob")); assertNotNull(person.getColumnByName("ssn")); Column name = person.getColumnByName("name"); Column dob = person.getColumnByName("dob"); Column ssn = person.getColumnByName("ssn"); assertEquals("string", name.getDatatype().getRuntimeTypeName()); assertEquals("timestamp", dob.getDatatype().getRuntimeTypeName()); assertEquals("long", ssn.getDatatype().getRuntimeTypeName()); assertTrue(name.getNullType() == NullType.No_Nulls); assertTrue(dob.getNullType() == NullType.Nullable); assertTrue(ssn.getNullType() == NullType.No_Nulls); assertEquals(25, name.getLength()); assertNotNull(person.getPrimaryKey()); assertEquals(1, person.getPrimaryKey().getColumns().size()); assertEquals("ssn", person.getPrimaryKey().getColumns().get(0).getName()); assertTrue(person.getForeignKeys().isEmpty()); } @Test public void testEnititySetWithComplexType() throws Exception { MetadataFactory mf = getEntityWithComplexProperty(); assertEquals(3, mf.getSchema().getTables().size()); assertNotNull(mf.getSchema().getTable("Persons")); assertNotNull(mf.getSchema().getTable("Persons_address")); assertNotNull(mf.getSchema().getTable("Persons_secondaddress")); Table personTable = mf.getSchema().getTable("Persons"); assertEquals(2, personTable.getColumns().size()); assertNotNull(personTable.getPrimaryKey()); Table addressTable = mf.getSchema().getTable("Persons_address"); assertEquals(4, addressTable.getColumns().size()); assertNotNull(addressTable.getColumnByName("ssn")); assertNotNull(addressTable.getColumnByName("ssn").getProperty(ODataMetadataProcessor.PSEUDO, false)); assertTrue(addressTable.getColumnByName("ssn").isSelectable()); assertEquals(1, addressTable.getForeignKeys().size()); assertEquals("Persons", addressTable.getForeignKeys().get(0).getReferenceTableName()); } static MetadataFactory getEntityWithComplexProperty() throws TranslatorException { ODataMetadataProcessor processor = new ODataMetadataProcessor(); MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); CsdlComplexType address = complexType("Address"); XMLMetadata metadata = buildXmlMetadata(createES("Persons", "namespace.Person"), buildPersonEntity(address), address); processor.getMetadata(mf, metadata); return mf; } @Test public void testMultipleEnititySetWithSameComplexType() throws Exception { ODataMetadataProcessor processor = new ODataMetadataProcessor(); MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); CsdlComplexType address = complexType("Address"); XMLMetadata metadata = buildXmlMetadata( createES("Persons", "namespace.Person"), buildPersonEntity(address), address, createES("Corporate", "namespace.Business"), buildBusinessEntity(address)); processor.getMetadata(mf, metadata); assertEquals(5, mf.getSchema().getTables().size()); assertNotNull(mf.getSchema().getTable("Persons")); assertNotNull(mf.getSchema().getTable("Corporate")); assertNotNull(mf.getSchema().getTable("Persons_address")); assertNotNull(mf.getSchema().getTable("Corporate_address")); Table personTable = mf.getSchema().getTable("Persons"); assertEquals(2, personTable.getColumns().size()); Table personAddress= mf.getSchema().getTable("Persons_address"); assertEquals(4, personAddress.getColumns().size()); ForeignKey fk = personAddress.getForeignKeys().get(0); assertNotNull(fk.getColumnByName("ssn")); Table businessTable = mf.getSchema().getTable("Corporate"); assertEquals(1, businessTable.getColumns().size()); Table corporateAddress= mf.getSchema().getTable("Corporate_address"); assertEquals(4, corporateAddress.getColumns().size()); fk = corporateAddress.getForeignKeys().get(0); assertNotNull(fk.getColumnByName("name")); } @Test public void testOneToOneAssosiation() throws Exception { MetadataFactory mf = oneToOneRelationMetadata(); Table g1 = mf.getSchema().getTable("G1"); Table g2 = mf.getSchema().getTable("G2"); ForeignKey fk = g2.getForeignKeys().get(0); assertEquals("one_2_one", fk.getName()); assertNotNull(fk.getColumnByName("e1")); } @Test public void testFunction() throws Exception { CsdlReturnType returnType = new CsdlReturnType(); returnType.setType("Edm.String"); MetadataFactory mf = functionMetadata("invoke", returnType, null); Procedure p = mf.getSchema().getProcedure("invoke"); assertNotNull(p); assertEquals(3, p.getParameters().size()); assertNull(p.getResultSet()); assertNotNull(getReturnParameter(p)); ProcedureParameter pp = getReturnParameter(p); assertEquals("string", pp.getRuntimeType()); ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false)); assertEquals(ODataType.FUNCTION, type); } @Test public void testAction() throws Exception { CsdlReturnType returnType = new CsdlReturnType(); returnType.setType("Edm.String"); MetadataFactory mf = actionMetadata("invoke", returnType, null); Procedure p = mf.getSchema().getProcedure("invoke"); assertNotNull(p); assertEquals(3, p.getParameters().size()); assertNull(p.getResultSet()); assertNotNull(getReturnParameter(p)); ProcedureParameter pp = getReturnParameter(p); assertEquals("string", pp.getRuntimeType()); ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false)); assertEquals(ODataType.ACTION, type); } @Test public void testFunctionReturnPrimitiveCollection() throws Exception { CsdlReturnType returnType = new CsdlReturnType(); returnType.setType("Edm.String"); returnType.setCollection(true); MetadataFactory mf = functionMetadata("invoke", returnType, null); Procedure p = mf.getSchema().getProcedure("invoke"); assertNotNull(p); assertEquals(3, p.getParameters().size()); assertNull(p.getResultSet()); assertNotNull(getReturnParameter(p)); ProcedureParameter pp = getReturnParameter(p); assertEquals("string[]", pp.getRuntimeType()); ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false)); assertEquals(ODataType.FUNCTION, type); } @Test public void testFunctionReturnComplex() throws Exception { CsdlComplexType complex = complexType("Address"); CsdlReturnType returnType = new CsdlReturnType(); returnType.setType("namespace.Address"); MetadataFactory mf = functionMetadata("invoke", returnType, complex); Procedure p = mf.getSchema().getProcedure("invoke"); assertNotNull(p); assertEquals(2, p.getParameters().size()); assertNotNull(p.getResultSet()); assertNull(getReturnParameter(p)); ColumnSet<Procedure> table = p.getResultSet(); ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false)); assertEquals(ODataType.FUNCTION, type); type = ODataType.valueOf(table.getProperty(ODataMetadataProcessor.ODATA_TYPE, false)); assertEquals(ODataType.COMPLEX, type); } @Test public void testFunctionReturnComplexCollection() throws Exception { CsdlComplexType complex = complexType("Address"); CsdlReturnType returnType = new CsdlReturnType(); returnType.setType("namespace.Address"); returnType.setCollection(true); MetadataFactory mf = functionMetadata("invoke", returnType, complex); Procedure p = mf.getSchema().getProcedure("invoke"); assertNotNull(p); assertEquals(2, p.getParameters().size()); assertNotNull(p.getResultSet()); assertNull(getReturnParameter(p)); ColumnSet<Procedure> table = p.getResultSet(); ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false)); assertEquals(ODataType.FUNCTION, type); type = ODataType.valueOf(table.getProperty(ODataMetadataProcessor.ODATA_TYPE, false)); assertEquals(ODataType.COMPLEX_COLLECTION, type); } private ProcedureParameter getReturnParameter(Procedure procedure) { for (ProcedureParameter pp:procedure.getParameters()) { if (pp.getType() == ProcedureParameter.Type.ReturnValue) { return pp; } } return null; } static MetadataFactory oneToOneRelationMetadata() throws TranslatorException { ODataMetadataProcessor processor = new ODataMetadataProcessor(); MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); CsdlEntityType g1Entity = entityType("g1"); CsdlEntityType g2Entity = entityType("g2"); CsdlNavigationProperty navProperty = new CsdlNavigationProperty(); navProperty.setName("one_2_one"); navProperty.setType("namespace.g2"); navProperty.setNullable(false); navProperty.setPartner("PartnerPath"); g1Entity.setNavigationProperties(Arrays.asList(navProperty)); CsdlEntitySet g1Set = createES("G1", "namespace.g1"); CsdlEntitySet g2Set = createES("G2", "namespace.g2"); CsdlNavigationPropertyBinding navBinding = new CsdlNavigationPropertyBinding(); navBinding.setPath("one_2_one"); navBinding.setTarget("G2"); g1Set.setNavigationPropertyBindings(Arrays.asList(navBinding)); XMLMetadata metadata = buildXmlMetadata(g1Entity, g1Set, g2Entity, g2Set); processor.getMetadata(mf, metadata); return mf; } static MetadataFactory functionMetadata(String name, CsdlReturnType returnType, Object other) throws TranslatorException { ODataMetadataProcessor processor = new ODataMetadataProcessor(); MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); CsdlFunction func = function(name, returnType); CsdlFunctionImport funcImport = new CsdlFunctionImport(); funcImport.setFunction(new FullQualifiedName("namespace."+name)); funcImport.setName(name); XMLMetadata metadata = buildXmlMetadata(funcImport, func, other); processor.getMetadata(mf, metadata); return mf; } static MetadataFactory actionMetadata(String name, CsdlReturnType returnType, Object other) throws TranslatorException { ODataMetadataProcessor processor = new ODataMetadataProcessor(); MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); CsdlAction func = action(name, returnType); CsdlActionImport funcImport = new CsdlActionImport(); funcImport.setAction(new FullQualifiedName("namespace."+name)); funcImport.setName(name); XMLMetadata metadata = buildXmlMetadata(funcImport, func, other); processor.getMetadata(mf, metadata); return mf; } @Test public void testSelfJoin() throws Exception { ODataMetadataProcessor processor = new ODataMetadataProcessor(); MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); CsdlEntityType g1Entity = entityType("g1"); CsdlNavigationProperty navProperty = new CsdlNavigationProperty(); navProperty.setName("self"); navProperty.setType("Collection(namespace.g1)"); navProperty.setNullable(false); navProperty.setPartner("PartnerPath"); navProperty.setCollection(true); g1Entity.setNavigationProperties(Arrays.asList(navProperty)); CsdlEntitySet g1Set = createES("G1", "namespace.g1"); CsdlNavigationPropertyBinding navBinding = new CsdlNavigationPropertyBinding(); navBinding.setPath("self"); navBinding.setTarget("G1"); g1Set.setNavigationPropertyBindings(Arrays.asList(navBinding)); XMLMetadata metadata = buildXmlMetadata(g1Entity, g1Set); processor.getMetadata(mf, metadata); Table g1 = mf.getSchema().getTable("G1_self"); assertNotNull(g1); assertEquals("self", g1.getForeignKeys().get(0).getName()); assertNotNull(g1.getForeignKeys().get(0).getColumnByName("G1_e1")); assertEquals("self", g1.getNameInSource()); } @Test public void testOneToManyAssosiation() throws Exception { MetadataFactory mf = oneToManyRelationMetadata(); Table g1 = mf.getSchema().getTable("G1"); Table g2 = mf.getSchema().getTable("G2"); ForeignKey fk = g2.getForeignKeys().get(0); assertEquals("one_2_many", fk.getName()); assertNotNull(fk.getColumnByName("e1")); } static MetadataFactory oneToManyRelationMetadata() throws TranslatorException { ODataMetadataProcessor processor = new ODataMetadataProcessor(); MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); CsdlEntityType g1Entity = entityType("g1"); CsdlEntityType g2Entity = multipleKeyEntityType("g2"); CsdlNavigationProperty navProperty = new CsdlNavigationProperty(); navProperty.setName("one_2_many"); navProperty.setType("Collection(namespace.g2)"); navProperty.setNullable(false); navProperty.setPartner("PartnerPath"); navProperty.setCollection(true); g1Entity.setNavigationProperties(Arrays.asList(navProperty)); CsdlEntitySet g1Set = createES("G1", "namespace.g1"); CsdlEntitySet g2Set = createES("G2", "namespace.g2"); CsdlNavigationPropertyBinding navBinding = new CsdlNavigationPropertyBinding(); navBinding.setPath("one_2_many"); navBinding.setTarget("G2"); g1Set.setNavigationPropertyBindings(Arrays.asList(navBinding)); XMLMetadata metadata = buildXmlMetadata(g1Entity, g1Set, g2Entity, g2Set); processor.getMetadata(mf, metadata); return mf; } static MetadataFactory multiplePKMetadata() throws TranslatorException { ODataMetadataProcessor processor = new ODataMetadataProcessor(); MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); CsdlEntityType entityType = multipleKeyEntityType("g1"); CsdlEntitySet entitySet = createES("G1", "namespace.g1"); XMLMetadata metadata = buildXmlMetadata(entityType, entitySet); processor.getMetadata(mf, metadata); return mf; } private static CsdlEntityType multipleKeyEntityType(String name) { ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>(); properties.add(createProperty("e1", EdmPrimitiveTypeKind.Int32)); properties.add(createProperty("e2", EdmPrimitiveTypeKind.String).setNullable(false)); properties.add(createProperty("e3", EdmPrimitiveTypeKind.String).setNullable(false)); CsdlEntityType entityType = new CsdlEntityType(); entityType.setName(name); entityType.setProperties(properties); entityType.setKey(Arrays.asList(new CsdlPropertyRef().setName("e1"), new CsdlPropertyRef().setName("e2"))); return entityType; } @Test public void testMultikeyPK() throws Exception { MetadataFactory mf = multiplePKMetadata(); Table g1 = mf.getSchema().getTable("G1"); assertNotNull(g1.getPrimaryKey().getColumnByName("e1")); assertNotNull(g1.getPrimaryKey().getColumnByName("e2")); assertNull(g1.getPrimaryKey().getColumnByName("e3")); } @Test public void testAssosiationWithReferentialContriant() throws Exception { ODataMetadataProcessor processor = new ODataMetadataProcessor(); MetadataFactory mf = new MetadataFactory("vdb", 1, "northwind", SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); CsdlEntityType g1Entity = entityType("g1"); g1Entity.getProperties().add(createProperty("g2e2", EdmPrimitiveTypeKind.String)); g1Entity.setKey(Arrays.asList(new CsdlPropertyRef().setName("g2e2"))); CsdlEntityType g2Entity = entityType("g2"); CsdlNavigationProperty navProperty = new CsdlNavigationProperty(); navProperty.setName("one_2_one"); navProperty.setType("namespace.g2"); navProperty.setNullable(false); navProperty.setPartner("PartnerPath"); navProperty.setReferentialConstraints(Arrays .asList(new CsdlReferentialConstraint().setProperty("g2e2") .setReferencedProperty("e2"))); g1Entity.setNavigationProperties(Arrays.asList(navProperty)); CsdlEntitySet g1Set = createES("G1", "namespace.g1"); CsdlEntitySet g2Set = createES("G2", "namespace.g2"); CsdlNavigationPropertyBinding navBinding = new CsdlNavigationPropertyBinding(); navBinding.setPath("one_2_one"); navBinding.setTarget("G2"); g1Set.setNavigationPropertyBindings(Arrays.asList(navBinding)); XMLMetadata metadata = buildXmlMetadata(g1Entity, g1Set, g2Entity, g2Set); processor.getMetadata(mf, metadata); Table g1 = mf.getSchema().getTable("G1"); Table g2 = mf.getSchema().getTable("G2"); assertNotNull(g1); assertNotNull(g2); ForeignKey fk = g2.getForeignKeys().get(0); assertEquals("one_2_one", fk.getName()); assertNotNull(fk.getColumnByName("e2")); assertEquals("g2e2", fk.getReferenceColumns().get(0)); } static CsdlEntityType entityType(String name) { ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>(); properties.add(createProperty("e1", EdmPrimitiveTypeKind.Int32)); properties.add(createProperty("e2", EdmPrimitiveTypeKind.String).setNullable(false)); CsdlEntityType entityType = new CsdlEntityType(); entityType.setName(name); entityType.setProperties(properties); entityType.setKey(Arrays.asList(new CsdlPropertyRef().setName("e1"))); return entityType; } static CsdlFunction function(String name, CsdlReturnType returnType) { ArrayList<CsdlParameter> parameters = new ArrayList<CsdlParameter>(); parameters.add(createParameter("e1", EdmPrimitiveTypeKind.Int32)); parameters.add(createParameter("e2", EdmPrimitiveTypeKind.String).setNullable(false)); CsdlFunction function = new CsdlFunction(); function.setName(name); function.setParameters(parameters); function.setReturnType(returnType); return function; } static CsdlAction action(String name, CsdlReturnType returnType) { ArrayList<CsdlParameter> parameters = new ArrayList<CsdlParameter>(); parameters.add(createParameter("e1", EdmPrimitiveTypeKind.Int32)); parameters.add(createParameter("e2", EdmPrimitiveTypeKind.String).setNullable(false)); CsdlAction action = new CsdlAction(); action.setName(name); action.setParameters(parameters); action.setReturnType(returnType); return action; } private CsdlEntityType buildBusinessEntity(CsdlComplexType address) { ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>(); properties.add(createProperty("name", EdmPrimitiveTypeKind.String).setMaxLength(25)); properties.add(new CsdlProperty().setName("address").setType(address.getName())); CsdlEntityType entityType = new CsdlEntityType(); entityType.setName("Business"); entityType.setProperties(properties); entityType.setKey(Arrays.asList(new CsdlPropertyRef().setName("name"))); return entityType; } static CsdlEntityType buildPersonEntity(CsdlComplexType address) { ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>(); properties.add(createProperty("name", EdmPrimitiveTypeKind.String).setMaxLength(25)); properties.add(createProperty("ssn", EdmPrimitiveTypeKind.Int64).setNullable(false)); properties.add(new CsdlProperty().setName("address").setType(address.getName())); properties.add(new CsdlProperty().setName("secondaddress").setType(address.getName())); CsdlEntityType entityType = new CsdlEntityType(); entityType.setName("Person"); entityType.setProperties(properties); entityType.setKey(Arrays.asList(new CsdlPropertyRef().setName("ssn"))); return entityType; } static CsdlComplexType complexType(String name) { ArrayList<CsdlProperty> properties = new ArrayList<CsdlProperty>(); properties.add(createProperty("street", EdmPrimitiveTypeKind.String)); properties.add(createProperty("city", EdmPrimitiveTypeKind.String)); properties.add(createProperty("state", EdmPrimitiveTypeKind.String)); CsdlComplexType type = new CsdlComplexType(); type.setName(name).setProperties(properties); return type; } }