/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * *************************************************************************************** */ package com.espertech.esper.regression.event; import com.espertech.esper.avro.core.AvroSchemaUtil; import com.espertech.esper.client.*; import com.espertech.esper.client.scopetest.SupportUpdateListener; import com.espertech.esper.collection.Pair; import com.espertech.esper.metrics.instrumentation.InstrumentationHelper; import com.espertech.esper.supportregression.bean.SupportBeanComplexProps; import com.espertech.esper.supportregression.bean.SupportBeanDynRoot; import com.espertech.esper.supportregression.client.SupportConfigFactory; import com.espertech.esper.supportregression.event.SupportEventInfra; import com.espertech.esper.supportregression.event.ValueWithExistsFlag; import junit.framework.TestCase; import org.apache.avro.Schema; import org.apache.avro.SchemaBuilder; import org.apache.avro.generic.GenericData; import org.w3c.dom.Node; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.function.Function; import static com.espertech.esper.supportregression.event.SupportEventInfra.*; import static com.espertech.esper.supportregression.event.ValueWithExistsFlag.allExist; import static com.espertech.esper.supportregression.event.ValueWithExistsFlag.exists; import static com.espertech.esper.supportregression.event.ValueWithExistsFlag.notExists; public class TestEventInfraPropertyNestedDynamicRootedNonSimple extends TestCase { private final static Class BEAN_TYPE = SupportBeanDynRoot.class; private EPServiceProvider epService; protected void setUp() { Configuration configuration = SupportConfigFactory.getConfiguration(); addXMLEventType(configuration); epService = EPServiceProviderManager.getDefaultProvider(configuration); epService.initialize(); addMapEventType(); addOAEventType(); epService.getEPAdministrator().getConfiguration().addEventType(BEAN_TYPE); addAvroEventType(); if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());} } public void tearDown() { if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();} } public void testIt() { final ValueWithExistsFlag[] NOT_EXISTS = ValueWithExistsFlag.multipleNotExists(6); // Bean SupportBeanComplexProps inner = SupportBeanComplexProps.makeDefaultBean(); Pair[] beanTests = new Pair[]{ new Pair<>(new SupportBeanDynRoot("xxx"), NOT_EXISTS), new Pair<>(new SupportBeanDynRoot(inner), allExist(inner.getIndexed(0), inner.getIndexed(1), inner.getArrayProperty()[1], inner.getMapped("keyOne"), inner.getMapped("keyTwo"), inner.getMapProperty().get("xOne"))), }; runAssertion(BEAN_TYPE.getSimpleName(), FBEAN, null, beanTests, Object.class); // Map Map<String, Object> mapNestedOne = new HashMap(); mapNestedOne.put("indexed", new int[] {1, 2}); mapNestedOne.put("arrayProperty", null); mapNestedOne.put("mapped", twoEntryMap("keyOne", 100, "keyTwo", 200)); mapNestedOne.put("mapProperty", null); Map<String, Object> mapOne = Collections.singletonMap("item", mapNestedOne); Pair[] mapTests = new Pair[]{ new Pair<>(Collections.emptyMap(), NOT_EXISTS), new Pair<>(mapOne, new ValueWithExistsFlag[] {exists(1), exists(2), notExists(), exists(100), exists(200), notExists()}), }; runAssertion(MAP_TYPENAME, FMAP, null, mapTests, Object.class); // Object-Array Object[] oaNestedOne = new Object[] {new int[] {1, 2}, twoEntryMap("keyOne", 100, "keyTwo", 200), new int[] {1000, 2000}, Collections.singletonMap("xOne", "abc")}; Object[] oaOne = new Object[] {null, oaNestedOne}; Pair[] oaTests = new Pair[]{ new Pair<>(new Object[] {null, null}, NOT_EXISTS), new Pair<>(oaOne, allExist(1, 2, 2000, 100, 200, "abc")), }; runAssertion(OA_TYPENAME, FOA, null, oaTests, Object.class); // XML Pair[] xmlTests = new Pair[]{ new Pair<>("", NOT_EXISTS), new Pair<>("<item>" + "<indexed>1</indexed><indexed>2</indexed><mapped id=\"keyOne\">3</mapped><mapped id=\"keyTwo\">4</mapped>" + "</item>", new ValueWithExistsFlag[] {exists("1"), exists("2"), notExists(), exists("3"), exists("4"), notExists()}) }; runAssertion(XML_TYPENAME, FXML, XML_TO_VALUE, xmlTests, Node.class); // Avro Schema schema = getAvroSchema(); Schema itemSchema = AvroSchemaUtil.findUnionRecordSchemaSingle(schema.getField("item").schema()); GenericData.Record datumOne = new GenericData.Record(schema); datumOne.put("item", null); GenericData.Record datumItemTwo = new GenericData.Record(itemSchema); datumItemTwo.put("indexed", Arrays.asList(1, 2)); datumItemTwo.put("mapped", twoEntryMap("keyOne", 3, "keyTwo", 4)); GenericData.Record datumTwo = new GenericData.Record(schema); datumTwo.put("item", datumItemTwo); Pair[] avroTests = new Pair[]{ new Pair<>(new GenericData.Record(schema), NOT_EXISTS), new Pair<>(datumOne, NOT_EXISTS), new Pair<>(datumTwo, new ValueWithExistsFlag[] {exists(1), exists(2), notExists(), exists(3), exists(4), notExists()}), }; runAssertion(AVRO_TYPENAME, FAVRO, null, avroTests, Object.class); } private void runAssertion(String typename, FunctionSendEvent send, Function<Object, Object> optionalValueConversion, Pair[] tests, Class expectedPropertyType) { String stmtText = "select " + "item?.indexed[0] as indexed1, " + "exists(item?.indexed[0]) as exists_indexed1, " + "item?.indexed[1]? as indexed2, " + "exists(item?.indexed[1]?) as exists_indexed2, " + "item?.arrayProperty[1]? as array, " + "exists(item?.arrayProperty[1]?) as exists_array, " + "item?.mapped('keyOne') as mapped1, " + "exists(item?.mapped('keyOne')) as exists_mapped1, " + "item?.mapped('keyTwo')? as mapped2, " + "exists(item?.mapped('keyTwo')?) as exists_mapped2, " + "item?.mapProperty('xOne')? as map, " + "exists(item?.mapProperty('xOne')?) as exists_map " + " from " + typename; EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText); SupportUpdateListener listener = new SupportUpdateListener(); stmt.addListener(listener); String[] propertyNames = "indexed1,indexed2,array,mapped1,mapped2,map".split(","); for (String propertyName : propertyNames) { assertEquals(expectedPropertyType, stmt.getEventType().getPropertyType(propertyName)); assertEquals(Boolean.class, stmt.getEventType().getPropertyType("exists_" + propertyName)); } for (Pair pair : tests) { send.apply(epService, pair.getFirst()); SupportEventInfra.assertValuesMayConvert(listener.assertOneGetNewAndReset(), propertyNames, (ValueWithExistsFlag[]) pair.getSecond(), optionalValueConversion); } stmt.destroy(); } private void addMapEventType() { epService.getEPAdministrator().getConfiguration().addEventType(MAP_TYPENAME, Collections.emptyMap()); } private void addOAEventType() { String nestedName = OA_TYPENAME+"_1"; String[] namesNested = {"indexed", "mapped", "arrayProperty", "mapProperty"}; Object[] typesNested = {int[].class, Map.class, int[].class, Map.class}; epService.getEPAdministrator().getConfiguration().addEventType(nestedName, namesNested, typesNested); String[] names = {"someprop", "item"}; Object[] types = {String.class, nestedName}; epService.getEPAdministrator().getConfiguration().addEventType(OA_TYPENAME, names, types); } private void addXMLEventType(Configuration configuration) { ConfigurationEventTypeXMLDOM eventTypeMeta = new ConfigurationEventTypeXMLDOM(); eventTypeMeta.setRootElementName("myevent"); String schema = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<xs:schema targetNamespace=\"http://www.espertech.com/schema/esper\" elementFormDefault=\"qualified\" xmlns:esper=\"http://www.espertech.com/schema/esper\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" + "\t<xs:element name=\"myevent\">\n" + "\t\t<xs:complexType>\n" + "\t\t</xs:complexType>\n" + "\t</xs:element>\n" + "</xs:schema>\n"; eventTypeMeta.setSchemaText(schema); configuration.addEventType(XML_TYPENAME, eventTypeMeta); } private void addAvroEventType() { epService.getEPAdministrator().getConfiguration().addEventTypeAvro(AVRO_TYPENAME, new ConfigurationEventTypeAvro(getAvroSchema())); } private static Schema getAvroSchema() { Schema s1 = SchemaBuilder.record(AVRO_TYPENAME+"_1").fields() .name("indexed").type().unionOf().nullType().and().intType().and().array().items().intType().endUnion().noDefault() .name("mapped").type().unionOf().nullType().and().intType().and().map().values().intType().endUnion().noDefault() .endRecord(); return SchemaBuilder.record(AVRO_TYPENAME).fields() .name("item").type().unionOf().intType().and().type(s1).endUnion().noDefault() .endRecord(); } }