blob: 8674e9f3484eaa2f0877deabd3fb708a7d6bf2ec [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.datatorrent.stram.webapp;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.Maps;
import com.datatorrent.api.DefaultInputPort;
import com.datatorrent.api.DefaultOutputPort;
import com.datatorrent.api.Operator;
import com.datatorrent.common.util.BaseOperator;
public class TypeDiscoveryTest
{
private static interface GenericInterface<T>
{
}
private static class StringOutputPort extends DefaultOutputPort<String>
{
public StringOutputPort(Operator operator)
{
super();
}
}
private static class A<K>
{
}
private static class B<T extends Number> extends A
{
}
private static class GenericOutputPort extends DefaultOutputPort<B<Number>>
{
public GenericOutputPort(Operator operator)
{
super();
}
}
private static class GenericSubClassOutputPort extends GenericOutputPort
{
public GenericSubClassOutputPort(Operator operator)
{
super(operator);
}
}
static class ParameterizedOperator<T0, T1 extends Map<String, ? extends T0>, T2 extends Number>
extends BaseOperator implements GenericInterface<T1>
{
final InputPort<T1> inputT1 = new DefaultInputPort<T1>()
{
@Override
public void process(T1 tuple)
{
}
};
final OutputPort<T2> outportT2 = new DefaultOutputPort<>();
final OutputPort<Number> outportNumberParam = new DefaultOutputPort<>();
final StringOutputPort outportString = new StringOutputPort(this);
final OutputPort<List<T0>> outportList = new DefaultOutputPort<>();
final GenericSubClassOutputPort outClassObject = new GenericSubClassOutputPort(this);
}
static class ExtendsParameterizedOperator extends ParameterizedOperator<Number, Map<String, Double>, Double>
{
}
static class SpecializedOperator extends BaseOperator
{
final InputPort<String> inputT1 = new DefaultInputPort<String>()
{
@Override
public void process(String tuple)
{
}
};
final OutputPort<Map<String, Number>> outportT2 = new DefaultOutputPort<>();
final OutputPort<Number> outportNumberParam = new DefaultOutputPort<>();
final StringOutputPort outportString = new StringOutputPort(this);
}
public static class DiscoveryContext
{
JSONObject json = new JSONObject();
Map<String, String> resolvedTypeParams = Maps.newHashMap();
}
@Test
public void testTypeDiscovery() throws Exception
{
String[] classFilePath = OperatorDiscoveryTest.getClassFileInClasspath();
OperatorDiscoverer od = new OperatorDiscoverer(classFilePath);
od.buildTypeGraph();
JSONObject Desc = od.describeClassByASM(ExtendsParameterizedOperator.class.getName());
JSONArray json = Desc.getJSONArray("portTypeInfo");
String debug = "\n(ASM)type info for " + ExtendsParameterizedOperator.class + ":\n" + Desc.toString(2) + "\n";
ObjectMapper mapper = new ObjectMapper();
//List<?> l = mapper.convertValue(json, List.class);
JsonNode root = mapper.readTree(json.toString(2));
String val = root.get(0).path("name").asText();
Assert.assertEquals(debug + "port name", "inputT1", val);
val = root.get(3).path("name").asText();
Assert.assertEquals(debug + "port name", "outportString", val);
val = root.get(3).path("type").asText();
Assert.assertEquals(debug + "outportList type", "java.lang.String", val);
val = root.get(4).path("name").asText();
Assert.assertEquals(debug + "port name", "outportList", val);
val = root.get(4).path("type").asText();
Assert.assertEquals(debug + "outportList type", "java.util.List", val);
val = root.get(4).path("typeArgs").get(0).path("type").asText();
Assert.assertEquals(debug + "outportList type", "java.lang.Number", val);
val = root.get(5).path("name").asText();
Assert.assertEquals(debug + "port name", "outClassObject", val);
val = root.get(5).path("type").asText();
Assert.assertEquals(debug + "outportList type", "com.datatorrent.stram.webapp.TypeDiscoveryTest$B", val);
val = root.get(5).path("typeArgs").get(0).path("type").asText();
Assert.assertEquals(debug + "outportList type", "java.lang.Number", val);
}
static class ParameterizedTypeOperator<T> extends BaseOperator
{
final OutputPort<T> output = new DefaultOutputPort<>();
}
static class StringParameterOperator extends ParameterizedTypeOperator<String>
{
}
@Test
public void testTypeDiscovery2() throws Exception
{
String[] classFilePath = OperatorDiscoveryTest.getClassFileInClasspath();
OperatorDiscoverer od = new OperatorDiscoverer(classFilePath);
od.buildTypeGraph();
JSONObject Desc = od.describeClassByASM(StringParameterOperator.class.getName());
JSONArray json = Desc.getJSONArray("portTypeInfo");
String debug = "\n(ASM)type info for " + StringParameterOperator.class + ":\n" + Desc.toString(2) + "\n";
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json.toString(2));
String val = root.get(0).path("name").asText();
Assert.assertEquals(debug + "port name", "output", val);
val = root.get(0).path("type").asText();
Assert.assertEquals(debug + "port type", "java.lang.String", val);
}
static class SubClass<K> extends ParameterizedTypeOperator<K>
{
}
static class SubSubClass extends SubClass<Map<String, Object>>
{
public String trial;
}
@Test
public void testTypeDiscoveryMultiLevel() throws Exception
{
String[] classFilePath = OperatorDiscoveryTest.getClassFileInClasspath();
OperatorDiscoverer od = new OperatorDiscoverer(classFilePath);
od.buildTypeGraph();
JSONObject Desc = od.describeClassByASM(SubSubClass.class.getName());
JSONArray json = Desc.getJSONArray("portTypeInfo");
String debug = "\n(ASM)type info for " + SubSubClass.class + ":\n" + Desc.toString(2) + "\n";
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json.toString(2));
String val = root.get(0).path("name").asText();
Assert.assertEquals(debug + "port name", "output", val);
val = root.get(0).path("type").asText();
Assert.assertEquals(debug + "port type", "java.util.Map", val);
val = root.get(0).path("typeArgs").get(0).path("type").asText();
Assert.assertEquals(debug + "map key type", "java.lang.String", val);
val = root.get(0).path("typeArgs").get(1).path("type").asText();
Assert.assertEquals(debug + "map value type", "java.lang.Object", val);
}
@Test
public void testAppAttributes() throws JSONException, IllegalAccessException
{
JSONArray appAttributes = TypeDiscoverer.getAppAttributes().getJSONArray("attributes");
Map<String, JSONObject> attributesMap = Maps.newHashMap();
for (int i = 0; i < appAttributes.length(); i++) {
attributesMap.put(appAttributes.getJSONObject(i).getString("name"), appAttributes.getJSONObject(i));
}
JSONObject appNameAttr = attributesMap.get("APPLICATION_NAME");
Assert.assertNotNull("application name", appNameAttr);
Assert.assertEquals("application name type", "java.lang.String", appNameAttr.getString("type"));
Assert.assertNotNull("default app name", appNameAttr.getString("default"));
JSONObject stringCodecsAttr = attributesMap.get("STRING_CODECS");
Assert.assertNotNull("string codecs", stringCodecsAttr);
Assert.assertEquals("string codecs type", "java.util.Map", stringCodecsAttr.getString("type"));
Assert.assertNotNull("type args", stringCodecsAttr.getJSONArray("typeArgs"));
}
@Test
public void testOperatorAttributes() throws JSONException, IllegalAccessException
{
JSONArray operatorAttributes = TypeDiscoverer.getOperatorAttributes().getJSONArray("attributes");
Map<String, JSONObject> attributesMap = Maps.newHashMap();
for (int i = 0; i < operatorAttributes.length(); i++) {
attributesMap.put(operatorAttributes.getJSONObject(i).getString("name"), operatorAttributes.getJSONObject(i));
}
JSONObject activationWindowAttr = attributesMap.get("ACTIVATION_WINDOW_ID");
Assert.assertNotNull("activation window", activationWindowAttr);
Assert.assertEquals("activation window type", "java.lang.Long", activationWindowAttr.getString("type"));
Assert.assertEquals("default activation window", "-1", activationWindowAttr.getString("default"));
JSONObject partitionerAttr = attributesMap.get("PARTITIONER");
Assert.assertNotNull("partitioner", partitionerAttr);
Assert.assertEquals("partitioner type", "com.datatorrent.api.Partitioner", partitionerAttr.getString("type"));
Assert.assertNotNull("type args", partitionerAttr.getJSONArray("typeArgs"));
JSONObject processingModeAttr = attributesMap.get("PROCESSING_MODE");
Assert.assertNotNull("processingModeAttr", processingModeAttr);
Assert.assertEquals("processing mode type", "com.datatorrent.api.Operator$ProcessingMode", processingModeAttr.getString("type"));
Assert.assertEquals("ui type", "Enum", processingModeAttr.getString("uiType"));
}
@Test
public void testPortAttributes() throws JSONException, IllegalAccessException
{
JSONArray portAttributes = TypeDiscoverer.getPortAttributes().getJSONArray("attributes");
Map<String, JSONObject> attributesMap = Maps.newHashMap();
for (int i = 0; i < portAttributes.length(); i++) {
attributesMap.put(portAttributes.getJSONObject(i).getString("name"), portAttributes.getJSONObject(i));
}
JSONObject queueCapacityAttr = attributesMap.get("QUEUE_CAPACITY");
Assert.assertNotNull("queue capacity", queueCapacityAttr);
Assert.assertEquals("queue capacity type", "java.lang.Integer", queueCapacityAttr.getString("type"));
Assert.assertEquals("default queue capacity", "1024", queueCapacityAttr.getString("default"));
JSONObject streamCodecAttr = attributesMap.get("STREAM_CODEC");
Assert.assertNotNull("stream codec", streamCodecAttr);
Assert.assertEquals("stream codec type", "com.datatorrent.api.StreamCodec", streamCodecAttr.getString("type"));
Assert.assertNotNull("type args", streamCodecAttr.getJSONArray("typeArgs"));
}
}