/* *************************************************************************************** * 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.SupportMarkerImplA; import com.espertech.esper.supportregression.bean.SupportMarkerInterface; 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.Collections; 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.*; public class TestEventInfraPropertyNestedDynamicRootedSimple extends TestCase { private final static Class BEAN_TYPE = SupportMarkerInterface.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 = multipleNotExists(3); // Bean Pair[] beanTests = new Pair[]{ new Pair<>(SupportBeanComplexProps.makeDefaultBean(), allExist("simple", "nestedValue", "nestedNestedValue")), new Pair<>(new SupportMarkerImplA("x"), NOT_EXISTS), }; runAssertion(BEAN_TYPE.getSimpleName(), FBEAN, null, beanTests, Object.class); // Map Map<String, Object> mapNestedNestedOne = Collections.singletonMap("nestedNestedValue", 101); Map<String, Object> mapNestedOne = twoEntryMap("nestedNested", mapNestedNestedOne, "nestedValue", "abc"); Map<String, Object> mapOne = twoEntryMap("simpleProperty", 5, "nested", mapNestedOne); Pair[] mapTests = new Pair[]{ new Pair<>(Collections.singletonMap("simpleProperty", "a"), new ValueWithExistsFlag[] {exists("a"), notExists(), notExists()}), new Pair<>(mapOne, allExist(5, "abc", 101)), }; runAssertion(MAP_TYPENAME, FMAP, null, mapTests, Object.class); // Object-Array Object[] oaNestedNestedOne = new Object[] {101}; Object[] oaNestedOne = new Object[] {"abc", oaNestedNestedOne}; Object[] oaOne = new Object[] {5, oaNestedOne}; Pair[] oaTests = new Pair[]{ new Pair<>(new Object[] {"a", null}, new ValueWithExistsFlag[] {exists("a"), notExists(), notExists()}), new Pair<>(oaOne, allExist(5, "abc", 101)), }; runAssertion(OA_TYPENAME, FOA, null, oaTests, Object.class); // XML Pair[] xmlTests = new Pair[]{ new Pair<>( "<simpleProperty>abc</simpleProperty>" + "<nested nestedValue=\"100\">\n" + "\t<nestedNested nestedNestedValue=\"101\">\n" + "\t</nestedNested>\n" + "</nested>\n", allExist("abc", "100", "101")), new Pair<>("<nested/>", NOT_EXISTS), }; runAssertion(XML_TYPENAME, FXML, XML_TO_VALUE, xmlTests, Node.class); // Avro GenericData.Record datumNull = new GenericData.Record(getAvroSchema()); Schema schema = getAvroSchema(); Schema nestedSchema = AvroSchemaUtil.findUnionRecordSchemaSingle(schema.getField("nested").schema()); Schema nestedNestedSchema = AvroSchemaUtil.findUnionRecordSchemaSingle(nestedSchema.getField("nestedNested").schema()); GenericData.Record nestedNestedDatum = new GenericData.Record(nestedNestedSchema); nestedNestedDatum.put("nestedNestedValue", 101); GenericData.Record nestedDatum = new GenericData.Record(nestedSchema); nestedDatum.put("nestedValue", 100); nestedDatum.put("nestedNested", nestedNestedDatum); GenericData.Record datumOne = new GenericData.Record(schema); datumOne.put("simpleProperty", "abc"); datumOne.put("nested", nestedDatum); Pair[] avroTests = new Pair[]{ new Pair<>(new GenericData.Record(SchemaBuilder.record(AVRO_TYPENAME).fields().endRecord()), NOT_EXISTS), new Pair<>(datumNull, new ValueWithExistsFlag[] {exists(null), notExists(), notExists()}), new Pair<>(datumOne, allExist("abc", 100, 101)), }; 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 " + "simpleProperty? as simple, "+ "exists(simpleProperty?) as exists_simple, "+ "nested?.nestedValue as nested, " + "exists(nested?.nestedValue) as exists_nested, " + "nested?.nestedNested.nestedNestedValue as nestedNested, " + "exists(nested?.nestedNested.nestedNestedValue) as exists_nestedNested " + "from " + typename; EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText); SupportUpdateListener listener = new SupportUpdateListener(); stmt.addListener(listener); String[] propertyNames = "simple,nested,nestedNested".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 type_2 = OA_TYPENAME + "_2"; String[] names_2 = {"nestedNestedValue"}; Object[] types_2 = {Object.class}; epService.getEPAdministrator().getConfiguration().addEventType(type_2, names_2, types_2); String type_1 = OA_TYPENAME + "_1"; String[] names_1 = {"nestedValue", "nestedNested"}; Object[] types_1 = {Object.class, type_2}; epService.getEPAdministrator().getConfiguration().addEventType(type_1, names_1, types_1); String[] names = {"simpleProperty", "nested"}; Object[] types = {Object.class, type_1}; 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 s3 = SchemaBuilder.record(AVRO_TYPENAME+"_3").fields() .optionalInt("nestedNestedValue") .endRecord(); Schema s2 = SchemaBuilder.record(AVRO_TYPENAME+"_2").fields() .optionalInt("nestedValue") .name("nestedNested").type().unionOf() .intType().and().type(s3).endUnion().noDefault() .endRecord(); return SchemaBuilder.record(AVRO_TYPENAME+"_1").fields() .name("simpleProperty").type().unionOf().intType().and().stringType().endUnion().noDefault() .name("nested").type().unionOf().intType().and().type(s2).endUnion().noDefault() .endRecord(); } }