/*
***************************************************************************************
* 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.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.*;
import com.espertech.esper.supportregression.client.SupportConfigFactory;
import com.espertech.esper.supportregression.event.SupportEventInfra;
import com.espertech.esper.supportregression.event.ValueWithExistsFlag;
import com.espertech.esper.util.EventRepresentationChoice;
import com.espertech.esper.util.JavaClassHelper;
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.avro.core.AvroConstant.PROP_JAVA_STRING_KEY;
import static com.espertech.esper.avro.core.AvroConstant.PROP_JAVA_STRING_VALUE;
import static com.espertech.esper.supportregression.event.SupportEventInfra.*;
import static com.espertech.esper.supportregression.event.SupportEventInfra.AVRO_TYPENAME;
import static com.espertech.esper.supportregression.event.ValueWithExistsFlag.exists;
import static com.espertech.esper.supportregression.event.ValueWithExistsFlag.notExists;
public class TestEventInfraPropertyNestedDynamic extends TestCase {
private final static String BEAN_TYPENAME = SupportBeanDynRoot.class.getName();
private static final FunctionSendEvent FAVRO = (epService, value) -> {
Schema schema = getAvroSchema();
Schema itemSchema = schema.getField("item").schema();
GenericData.Record itemDatum = new GenericData.Record(itemSchema);
itemDatum.put("id", value);
GenericData.Record datum = new GenericData.Record(schema);
datum.put("item", itemDatum);
epService.getEPRuntime().sendEventAvro(datum, AVRO_TYPENAME);
};
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_TYPENAME, SupportBeanDynRoot.class);
addAvroEventType();
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());}
}
public void tearDown() {
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();}
}
public void testDynamicProp() {
runAssertion(EventRepresentationChoice.ARRAY, "");
runAssertion(EventRepresentationChoice.MAP, "");
runAssertion(EventRepresentationChoice.AVRO, "@AvroSchemaField(name='myid',schema='[\"int\",{\"type\":\"string\",\"avro.java.string\":\"String\"},\"null\"]')");
runAssertion(EventRepresentationChoice.DEFAULT, "");
}
private void runAssertion(EventRepresentationChoice outputEventRep, String additionalAnnotations) {
// Bean
Pair[] beanTests = new Pair[]{
new Pair<>(new SupportBeanDynRoot(new SupportBean_S0(101)), exists(101)),
new Pair<>(new SupportBeanDynRoot("abc"), notExists()),
new Pair<>(new SupportBeanDynRoot(new SupportBean_A("e1")), exists("e1")),
new Pair<>(new SupportBeanDynRoot(new SupportBean_B("e2")), exists("e2")),
new Pair<>(new SupportBeanDynRoot(new SupportBean_S1(102)), exists(102))
};
runAssertion(outputEventRep, additionalAnnotations, BEAN_TYPENAME, FBEAN, null, beanTests, Object.class);
// Map
Pair[] mapTests = new Pair[]{
new Pair<>(Collections.emptyMap(), notExists()),
new Pair<>(Collections.singletonMap("item", Collections.singletonMap("id", 101)), exists(101)),
new Pair<>(Collections.singletonMap("item", Collections.emptyMap()), notExists()),
};
runAssertion(outputEventRep, additionalAnnotations, MAP_TYPENAME, FMAP, null, mapTests, Object.class);
// Object array
Pair[] oaTests = new Pair[]{
new Pair<>(new Object[] {null}, notExists()),
//new Pair<>(new Object[] {new SupportBean_S0(101)}, exists(101)),
//new Pair<>(new Object[] {"abc"}, notExists()),
};
runAssertion(outputEventRep, additionalAnnotations, OA_TYPENAME, FOA, null, oaTests, Object.class);
// XML
Pair[] xmlTests = new Pair[]{
new Pair<>("<item id=\"101\"/>", exists("101")),
new Pair<>("<item/>", notExists()),
};
if (!outputEventRep.isAvroEvent()) {
runAssertion(outputEventRep, additionalAnnotations, XML_TYPENAME, FXML, XML_TO_VALUE, xmlTests, Node.class);
}
// Avro
Pair[] avroTests = new Pair[]{
new Pair<>(null, exists(null)),
new Pair<>(101, exists(101)),
new Pair<>("abc", exists("abc")),
};
runAssertion(outputEventRep, additionalAnnotations, AVRO_TYPENAME, FAVRO, null, avroTests, Object.class);
}
private void runAssertion(EventRepresentationChoice eventRepresentationEnum,
String additionalAnnotations,
String typename,
FunctionSendEvent send,
Function<Object, Object> optionalValueConversion,
Pair[] tests,
Class expectedPropertyType) {
String stmtText = eventRepresentationEnum.getAnnotationText() + additionalAnnotations + " select " +
"item.id? as myid, " +
"exists(item.id?) as exists_myid " +
"from " + typename;
EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
SupportUpdateListener listener = new SupportUpdateListener();
stmt.addListener(listener);
assertEquals(expectedPropertyType, stmt.getEventType().getPropertyType("myid"));
assertEquals(Boolean.class, JavaClassHelper.getBoxedType(stmt.getEventType().getPropertyType("exists_myid")));
assertTrue(eventRepresentationEnum.matchesClass(stmt.getEventType().getUnderlyingType()));
for (Pair pair : tests) {
send.apply(epService, pair.getFirst());
EventBean event = listener.assertOneGetNewAndReset();
SupportEventInfra.assertValueMayConvert(event, "myid", (ValueWithExistsFlag) pair.getSecond(), optionalValueConversion);
}
stmt.destroy();
}
private void addMapEventType() {
Map<String, Object> top = Collections.singletonMap("item", Map.class);
epService.getEPAdministrator().getConfiguration().addEventType(MAP_TYPENAME, top);
}
private void addOAEventType() {
String[] names = {"item"};
Object[] types = {Object.class};
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\t<xs:sequence>\n" +
"\t\t\t\t<xs:element ref=\"esper:item\"/>\n" +
"\t\t\t</xs:sequence>\n" +
"\t\t</xs:complexType>\n" +
"\t</xs:element>\n" +
"\t<xs:element name=\"item\">\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("id").type().unionOf()
.intBuilder().endInt()
.and()
.stringBuilder().prop(PROP_JAVA_STRING_KEY, PROP_JAVA_STRING_VALUE).endString()
.and()
.nullType()
.endUnion().noDefault()
.endRecord();
return SchemaBuilder.record(AVRO_TYPENAME).fields().name("item").type(s1).noDefault().endRecord();
}
}