/** * Prints a TBase. * * @param t The object to print. * @param depth The print nesting level. * @return The pretty-printed version of the TBase. */ private static String printTbase(TBase t, int depth) { List<String> fields = Lists.newArrayList(); for (Map.Entry<? extends TFieldIdEnum, FieldMetaData> entry : FieldMetaData.getStructMetaDataMap(t.getClass()).entrySet()) { @SuppressWarnings("unchecked") boolean fieldSet = t.isSet(entry.getKey()); String strValue; if (fieldSet) { @SuppressWarnings("unchecked") Object value = t.getFieldValue(entry.getKey()); strValue = printValue(value, depth); } else { strValue = "not set"; } fields.add(tabs(depth) + entry.getValue().fieldName + ": " + strValue); } return Joiner.on("\n").join(fields); }
/** * Struct use only. * * @return */ public TField newField() { if (createIndex < obj.length()) { Map.Entry<TFieldIdEnum, FieldMetaData> entry = null; if (addStep == 2) { String fieldName = obj.getString(createIndex << 1); entry = elementMetas.get(fieldName); createIndex++; } else { int i = createIndex; Object o; while (i < obj.length() && ((o = obj.get(i)) == null || o == JSONObject.NULL)) { currentIndex();// array index: +1 i++; } entry = elementMetaArr[i]; createIndex = i + 1; } FieldMetaData fm = entry.getValue(); prevFieldMetaData = fm; return new TField(fm.fieldName, fm.valueMetaData.type, entry.getKey().getThriftFieldId()); } return null; }
public static Map<String, Object> thriftToMap( org.apache.thrift.TBase thriftObj) { Map<String, Object> ret = new HashMap<String, Object>(); int i = 1; TFieldIdEnum field = thriftObj.fieldForId(i); while(field != null) { if (thriftObj.isSet(field)) { Object obj = thriftObj.getFieldValue(field); ret.put(field.getFieldName(), thriftToObject(obj)); } field = thriftObj.fieldForId(++i); } return ret; }
private static RpcRequest toRpcRequest(Class<?> serviceType, String method, TBase<?, ?> thriftArgs) { requireNonNull(thriftArgs, "thriftArgs"); // NB: The map returned by FieldMetaData.getStructMetaDataMap() is an EnumMap, // so the parameter ordering is preserved correctly during iteration. final Set<? extends TFieldIdEnum> fields = FieldMetaData.getStructMetaDataMap(thriftArgs.getClass()).keySet(); // Handle the case where the number of arguments is 0 or 1. final int numFields = fields.size(); switch (numFields) { case 0: return RpcRequest.of(serviceType, method); case 1: return RpcRequest.of(serviceType, method, ThriftFieldAccess.get(thriftArgs, fields.iterator().next())); } // Handle the case where the number of arguments is greater than 1. final List<Object> list = new ArrayList<>(numFields); for (TFieldIdEnum field : fields) { list.add(ThriftFieldAccess.get(thriftArgs, field)); } return RpcRequest.of(serviceType, method, list); }
/** * Converts the specified {@code result} into a Java object. */ public Object getResult(TBase<?, ?> result) throws TException { for (TFieldIdEnum fieldIdEnum : exceptionFields()) { if (ThriftFieldAccess.isSet(result, fieldIdEnum)) { throw (TException) ThriftFieldAccess.get(result, fieldIdEnum); } } final TFieldIdEnum successField = successField(); if (successField == null) { //void method return null; } else if (ThriftFieldAccess.isSet(result, successField)) { return ThriftFieldAccess.get(result, successField); } else { throw new TApplicationException( TApplicationException.MISSING_RESULT, result.getClass().getName() + '.' + successField.getFieldName()); } }
/** * To consume a list of elements * @param c the type of the list content * @param consumer the consumer that will receive the list * @return a ListConsumer that can be passed to the DelegatingFieldConsumer */ public static <T extends TBase<T,? extends TFieldIdEnum>> ListConsumer listOf(Class<T> c, final Consumer<List<T>> consumer) { class ListConsumer implements Consumer<T> { List<T> list; @Override public void consume(T t) { list.add(t); } } final ListConsumer co = new ListConsumer(); return new DelegatingListElementsConsumer(struct(c, co)) { @Override public void consumeList(TProtocol protocol, EventBasedThriftReader reader, TList tList) throws TException { co.list = new ArrayList<T>(); super.consumeList(protocol, reader, tList); consumer.consume(co.list); } }; }
public ThriftRecordReader(File dataFile, Schema schema, ThriftRecordReaderConfig recordReaderConfig) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException { this._schema = schema; this._dataFile = dataFile; this._recordReaderConfig = recordReaderConfig; this._thriftClass = initThriftInstanceCreator(); this._bufferIn = RecordReaderUtils.getFileBufferStream(dataFile); this._binaryIn = new TBinaryProtocol(new TIOStreamTransport(_bufferIn)); this._fieldNameToIndexMap = new HashMap(); TBase t = this._thriftClass.newInstance(); int index = 1; TFieldIdEnum fieldIdEnum = null; do { fieldIdEnum = t.fieldForId(index); if (fieldIdEnum != null) { _fieldNameToIndexMap.put(fieldIdEnum.getFieldName(), index); } index = index + 1; } while (fieldIdEnum != null); }
private void pushWriteField(Class<? extends TBase> tbase, String fieldName) throws TException { //get the field ID by name org.apache.thrift.TFieldIdEnum tfieldIdEnum = getFieldId(tbase, fieldName); if(tfieldIdEnum!=null) { //pushWriteField(tfieldIdEnum.getThriftFieldId()); Stack<ThriftFieldMetadata> writeStack = threadSafeFieldsStack.get(); // First push if(writeStack==null) { writeStack = new Stack<>(); } // Take the tbase class at the top of the stack ThriftFieldMetadata thriftFieldMetadata = getTBaseFields(tbase).get(tfieldIdEnum.getThriftFieldId()); writeStack.push(thriftFieldMetadata); threadSafeFieldsStack.set(writeStack); } }
public static Map<String, Object> thriftToMap( org.apache.thrift.TBase thriftObj) { Map<String, Object> ret = new HashMap<>(); int i = 1; TFieldIdEnum field = thriftObj.fieldForId(i); while (field != null) { if (thriftObj.isSet(field)) { Object obj = thriftObj.getFieldValue(field); ret.put(field.getFieldName(), thriftToObject(obj)); } field = thriftObj.fieldForId(++i); } return ret; }
@SuppressWarnings({"unchecked", "rawtypes"}) private static TUnion<?, ?> createUnion( Class<?> unionType, TFieldIdEnum setField, Object fieldValue) throws IllegalAccessException, InstantiationException { TUnion union = (TUnion) unionType.newInstance(); union.setFieldValue(setField, fieldValue); return union; }
private static Map<TFieldIdEnum, FieldMetaData> getMetadataMap(Class c) { try { Object o = c.newInstance(); return (Map) c.getField("metaDataMap").get(o); } catch (Exception e) { throw new RuntimeException(e); } }
private static TFieldIdEnum getIdForClass( Map<TFieldIdEnum, FieldMetaData> meta, Class toFind) { for(TFieldIdEnum k: meta.keySet()) { FieldValueMetaData md = meta.get(k).valueMetaData; if(md instanceof StructMetaData) { if(toFind.equals(((StructMetaData) md).structClass)) { return k; } } } throw new RuntimeException("Could not find " + toFind.toString() + " in " + meta.toString()); }
public PropertyStructure(Class prop) { try { Map<TFieldIdEnum, FieldMetaData> propMeta = getMetadataMap(prop); Class valClass = Class.forName(prop.getName() + "Value"); valueId = getIdForClass(propMeta, valClass); validIds = new HashSet<Short>(); Map<TFieldIdEnum, FieldMetaData> valMeta = getMetadataMap(valClass); for(TFieldIdEnum valId: valMeta.keySet()) { validIds.add(valId.getThriftFieldId()); } } catch(Exception e) { throw new RuntimeException(e); } }
/** * Sets the exception field of the specified {@code result} to the specified {@code cause}. */ public boolean setException(TBase<?, ?> result, Throwable cause) { Class<?> causeType = cause.getClass(); for (Entry<Class<Throwable>, TFieldIdEnum> e : exceptionFields.entrySet()) { if (e.getKey().isAssignableFrom(causeType)) { ThriftFieldAccess.set(result, e.getValue(), cause); return true; } } return false; }
private static TFieldIdEnum[] getArgFields0(Type type, Class<?> funcClass, String methodName) { final String fieldIdEnumTypeName = typeName(type, funcClass, methodName, methodName + "_args$_Fields"); try { Class<?> fieldIdEnumType = Class.forName(fieldIdEnumTypeName, false, funcClass.getClassLoader()); return (TFieldIdEnum[]) requireNonNull(fieldIdEnumType.getEnumConstants(), "field enum may not be empty"); } catch (Exception e) { throw new IllegalStateException("cannot determine the arg fields of method: " + methodName, e); } }
/** * Gets the value of the specified struct field. */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static Object get(TBase<?, ?> struct, TFieldIdEnum field) { final Object value = ((TBase) struct).getFieldValue(field); if (value instanceof byte[]) { return ByteBuffer.wrap((byte[]) value); } else { return value; } }
@Override public GenericRow next(GenericRow reuse) throws IOException { TBase t = null; try { t = this._thriftClass.newInstance(); t.read(_binaryIn); } catch (Exception e) { throw new RuntimeException("Caught exception while serialize thrift instance", e); } for (FieldSpec fieldSpec : _schema.getAllFieldSpecs()) { String fieldName = fieldSpec.getName(); if (_fieldNameToIndexMap.containsKey(fieldName)) { int tFieldId = _fieldNameToIndexMap.get(fieldName); TFieldIdEnum tFieldIdEnum = t.fieldForId(tFieldId); Object thriftValue = t.getFieldValue(tFieldIdEnum); Object value = null; if (fieldSpec.isSingleValueField()) { String token = thriftValue != null ? thriftValue.toString() : null; value = RecordReaderUtils.convertToDataType(token, fieldSpec); } else { if(thriftValue instanceof ArrayList) { value = RecordReaderUtils.convertToDataTypeArray((ArrayList) thriftValue, fieldSpec); } else if(thriftValue instanceof HashSet) { value = RecordReaderUtils.convertToDataTypeSet((HashSet) thriftValue, fieldSpec); } } reuse.putField(fieldName, value); } } return reuse; }
public void setFieldIdsFilter(TBase<?, ?> base, TFieldIdEnum[] fieldIds) { base.getClass(); List<Short> filteredFields = new ArrayList<>(); for(TFieldIdEnum tFieldIdEnum : fieldIds){ filteredFields.add(tFieldIdEnum.getThriftFieldId()); } Map<Class<?>,List<Short>> filter = new HashMap<>(); filter.put(base.getClass(), filteredFields); threadSafeFieldIds.set(filter); }
private Map<String, ThriftField> getClassFields(Object thriftObject) throws TException { try { Map<Class<?>,Map<String, ThriftField>> thriftFields = threadSafeTFields.get(); if(thriftFields==null){ thriftFields = new HashMap<>(); } Class<?> tbase = thriftObject.getClass(); Map<String, ThriftField> classTFields = thriftFields.get(tbase); if(classTFields!=null){ return classTFields; } classTFields = new HashMap<>(); Field metafaField = thriftObject.getClass().getField("metaDataMap"); Map<?, org.apache.thrift.meta_data.FieldMetaData> fields = (Map<?, org.apache.thrift.meta_data.FieldMetaData>) metafaField.get(thriftObject); // recurse on all sub structures for (Entry<?, org.apache.thrift.meta_data.FieldMetaData> entry : fields.entrySet()) { TFieldIdEnum field = (TFieldIdEnum) entry.getKey(); classTFields.put(field.getFieldName(), new ThriftField(field, entry.getValue())); } thriftFields.put(tbase, classTFields); threadSafeTFields.set(thriftFields); return classTFields; } catch (Exception exp) { throw new TException("Unexpected object", exp); } }
public void setFieldIdsFilter(TBase<?, ?> base, TFieldIdEnum[] fieldIds) { base.getClass(); List<Short> filteredFields = new ArrayList<>(); for(TFieldIdEnum tFieldIdEnum : fieldIds){ filteredFields.add(tFieldIdEnum.getThriftFieldId()); } Map<Class<?>,List<Short>> filter = new HashMap<>(); filter.put(base.getClass(), filteredFields); threadSafeFieldIdsFilter.set(filter); }
public org.apache.thrift.TFieldIdEnum getFieldId(Class<? extends TBase> tbase, String fieldName) throws TException { try { Map<Class<?>,Map<String,org.apache.thrift.TFieldIdEnum>> thriftTFields = threadSafeTFieldsIdEnum.get(); if(thriftTFields==null){ thriftTFields = new HashMap<>(); } Map<String,org.apache.thrift.TFieldIdEnum> tfieldIdEnumByName = thriftTFields.get(tbase); // Load it in cache if(tfieldIdEnumByName==null) { Class<?>[] innerClasses = tbase.getClasses(); for (Class<?> innerClass : innerClasses) { if ("_Fields".equals(innerClass.getSimpleName())) { Field fieldsByName = innerClass.getDeclaredField("byName"); fieldsByName.setAccessible(true); tfieldIdEnumByName = (Map<String, org.apache.thrift.TFieldIdEnum>) fieldsByName.get(fieldsByName); // store in the thread local thriftTFields.put(tbase, tfieldIdEnumByName); threadSafeTFieldsIdEnum.set(thriftTFields); } } } return tfieldIdEnumByName.get(fieldName); } catch (Exception e) { throw new TException(e); } }
public DBObject getBSON(String prefix, Class<? extends TBase> tbase, TFieldIdEnum field, String value) throws TException { try { DBObject bson = new BasicDBObject(); ThriftSecuredField securedField = getField(tbase, field.getThriftFieldId()); StringBuilder builder = new StringBuilder(); if (prefix != null && prefix.length() > 0) { builder.append(prefix); builder.append("."); } builder.append(field.getFieldName()); if (!securedField.isSecured()) { bson.put( builder.toString(), value); } // adds the hash if necessary if (securedField.isHash()) { bson.put( builder.toString() , digest64(value.getBytes())); } builder = new StringBuilder(); if (prefix != null && prefix.length() > 0) { builder.append(prefix); builder.append("."); } builder.append("securedwrap."); builder.append(Short.toString(field.getThriftFieldId())); // adds the wrapped value if necessary bson.put( builder.toString(), Hex.encodeHexString(cipher(value.getBytes("UTF-8")))); return bson; } catch (UnsupportedEncodingException e) { throw new TException(e); } }
/** * Deserialize only a single Thrift object * from a byte record. * @param base The object to read into * @param dbObject The serialized object to read from * @param fieldIds The FieldId's to extract * @throws TException */ public void partialDeserialize(TBase<?,?> base, DBObject dbObject, TFieldIdEnum... fieldIds) throws TException { try { protocol_.setDBOject(dbObject); protocol_.setBaseObject( base ); protocol_.setFieldIdsFilter(base, fieldIds); base.read(protocol_); } finally { protocol_.reset(); } }
/** * Attempts to find the {@link T}, aka a 'thrift-like object', in the row. * * @return a {@link T} if found * @throws RebarException * - if there is no {@link T} in this row, or if there was an error during serialization */ public <T extends TBase<T, ? extends TFieldIdEnum>> T extract(T object, String stageName) throws RebarException { try { byte[] bytez = this.extractBytes(stageName, ColType.CQ); new TDeserializer(new TBinaryProtocol.Factory()).deserialize(object, bytez); return object; } catch (TException e) { throw new RebarException(e); } }
@SuppressWarnings("unchecked") public BaseArray(FieldValueMetaData meta, ArrayJson obj) { this.obj = obj; this.metaData = meta; ARRAY_SIZE = obj.arraySize(); int addStep = 1; if (meta.type == TType.STRUCT) { StructMetaData sm = (StructMetaData) meta; Map<TFieldIdEnum, FieldMetaData> map = (Map<TFieldIdEnum, FieldMetaData>) FieldMetaData .getStructMetaDataMap(sm.structClass); if (obj instanceof JSONObject) { this.fieldIndex = 1; addStep = 2; if (map != null && map.size() > 0) { elementMetas = new HashMap<String, Map.Entry<TFieldIdEnum, FieldMetaData>>(map.size()); for (Map.Entry<TFieldIdEnum, FieldMetaData> m : map.entrySet()) { TFieldIdEnum k = m.getKey(); // fieldName <-> metaData elementMetas.put(k.getFieldName(), m); // id <-> metaData elementMetas.put(String.valueOf(k.getThriftFieldId()), m); } } String fieldName = obj.getString(0); if (!useId && fieldName.length() > 0) { char c0 = fieldName.charAt(0); useId = c0 >= '0' && c0 <= '9'; } } else { elementMetaArr = map.entrySet().toArray(new Map.Entry[0]); Arrays.sort(elementMetaArr, new Comparator<Map.Entry<TFieldIdEnum, FieldMetaData>>() { @Override public int compare(Entry<TFieldIdEnum, FieldMetaData> o1, Entry<TFieldIdEnum, FieldMetaData> o2) { return o1.getKey().getThriftFieldId() - o2.getKey().getThriftFieldId(); } }); } } this.addStep = addStep; }
public static void addStructMetaDataMap(Class<? extends TBase> sClass, Map<? extends TFieldIdEnum, FieldMetaData> map){ structMap.put(sClass, map); }
private void handle(ClientRequestContext ctx, int seqId, DefaultRpcResponse reply, ThriftFunction func, HttpData content) throws TException { if (func.isOneWay()) { handleSuccess(ctx, reply, null, null); return; } if (content.isEmpty()) { throw new TApplicationException(TApplicationException.MISSING_RESULT); } final TMemoryInputTransport inputTransport = new TMemoryInputTransport(content.array(), content.offset(), content.length()); final TProtocol inputProtocol = protocolFactory.getProtocol(inputTransport); final TMessage header = inputProtocol.readMessageBegin(); final TApplicationException appEx = readApplicationException(seqId, func, inputProtocol, header); if (appEx != null) { handleException(ctx, reply, new ThriftReply(header, appEx), appEx); return; } TBase<?, ?> result = func.newResult(); result.read(inputProtocol); inputProtocol.readMessageEnd(); final ThriftReply rawResponseContent = new ThriftReply(header, result); for (TFieldIdEnum fieldIdEnum : func.exceptionFields()) { if (ThriftFieldAccess.isSet(result, fieldIdEnum)) { final TException cause = (TException) ThriftFieldAccess.get(result, fieldIdEnum); handleException(ctx, reply, rawResponseContent, cause); return; } } final TFieldIdEnum successField = func.successField(); if (successField == null) { // void method handleSuccess(ctx, reply, null, rawResponseContent); return; } if (ThriftFieldAccess.isSet(result, successField)) { final Object returnValue = ThriftFieldAccess.get(result, successField); handleSuccess(ctx, reply, returnValue, rawResponseContent); return; } handleException( ctx, reply, rawResponseContent, new TApplicationException(TApplicationException.MISSING_RESULT, result.getClass().getName() + '.' + successField.getFieldName())); }
private ThriftFunction( Class<?> serviceType, String name, Object func, Type type, TFieldIdEnum[] argFields, TBase<?, ?> result, Class<?>[] declaredExceptions) throws Exception { this.func = func; this.type = type; this.serviceType = serviceType; this.name = name; this.argFields = argFields; this.result = result; this.declaredExceptions = declaredExceptions; // Determine the success and exception fields of the function. final ImmutableMap.Builder<Class<Throwable>, TFieldIdEnum> exceptionFieldsBuilder = ImmutableMap.builder(); TFieldIdEnum successField = null; if (result != null) { // if not oneway @SuppressWarnings("unchecked") final Class<? extends TBase<?, ?>> resultType = (Class<? extends TBase<?, ?>>) result.getClass(); @SuppressWarnings("unchecked") final Map<TFieldIdEnum, FieldMetaData> metaDataMap = (Map<TFieldIdEnum, FieldMetaData>) FieldMetaData.getStructMetaDataMap(resultType); for (Entry<TFieldIdEnum, FieldMetaData> e : metaDataMap.entrySet()) { final TFieldIdEnum key = e.getKey(); final String fieldName = key.getFieldName(); if ("success".equals(fieldName)) { successField = key; continue; } Class<?> fieldType = resultType.getField(fieldName).getType(); if (Throwable.class.isAssignableFrom(fieldType)) { @SuppressWarnings("unchecked") Class<Throwable> exceptionFieldType = (Class<Throwable>) fieldType; exceptionFieldsBuilder.put(exceptionFieldType, key); } } } this.successField = successField; exceptionFields = exceptionFieldsBuilder.build(); }
/** * Returns the field that holds the successful result. */ public TFieldIdEnum successField() { return successField; }
/** * Returns the field that holds the exception. */ public Collection<TFieldIdEnum> exceptionFields() { return exceptionFields.values(); }
private static TFieldIdEnum[] getArgFields(ProcessFunction<?, ?> func) { return getArgFields0(Type.SYNC, func.getClass(), func.getMethodName()); }
private static TFieldIdEnum[] getArgFields(AsyncProcessFunction<?, ?, ?> asyncFunc) { return getArgFields0(Type.ASYNC, asyncFunc.getClass(), asyncFunc.getMethodName()); }
/** * Sets the value of the specified struct field. */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static void set(TBase<?, ?> struct, TFieldIdEnum field, Object value) { ((TBase) struct).setFieldValue(field, value); }
/** * Tells whether the specified struct field is set or not. */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static boolean isSet(TBase<?, ?> struct, TFieldIdEnum field) { return ((TBase) struct).isSet(field); }
/** * Compute a new field name map for the current thrift message * we are parsing. */ private Map<String, TField> computeFieldNameMap(Class<?> clazz) { Map<String, TField> map = new HashMap<>(); if (isTBase(clazz)) { // Get the metaDataMap for this Thrift class @SuppressWarnings("unchecked") Map<? extends TFieldIdEnum, FieldMetaData> metaDataMap = FieldMetaData.getStructMetaDataMap((Class<? extends TBase<?, ?>>) clazz); for (Entry<? extends TFieldIdEnum, FieldMetaData> e : metaDataMap.entrySet()) { final String fieldName = e.getKey().getFieldName(); final FieldMetaData metaData = e.getValue(); final FieldValueMetaData elementMetaData; if (metaData.valueMetaData.isContainer()) { if (metaData.valueMetaData instanceof SetMetaData) { elementMetaData = ((SetMetaData) metaData.valueMetaData).elemMetaData; } else if (metaData.valueMetaData instanceof ListMetaData) { elementMetaData = ((ListMetaData) metaData.valueMetaData).elemMetaData; } else if (metaData.valueMetaData instanceof MapMetaData) { elementMetaData = ((MapMetaData) metaData.valueMetaData).valueMetaData; } else { // Unrecognized container type, but let's still continue processing without // special enum support. elementMetaData = metaData.valueMetaData; } } else { elementMetaData = metaData.valueMetaData; } if (elementMetaData instanceof EnumMetaData) { classMap.put(fieldName, ((EnumMetaData) elementMetaData).enumClass); } else if (elementMetaData instanceof StructMetaData) { classMap.put(fieldName, ((StructMetaData) elementMetaData).structClass); } // Workaround a bug in the generated thrift message read() // method by mapping the ENUM type to the INT32 type // The thrift generated parsing code requires that, when expecting // a value of enum, we actually parse a value of type int32. The // generated read() method then looks up the enum value in a map. byte type = TType.ENUM == metaData.valueMetaData.type ? TType.I32 : metaData.valueMetaData.type; map.put(fieldName, new TField(fieldName, type, e.getKey().getThriftFieldId())); } } else { // TApplicationException map.put("message", new TField("message", (byte)11, (short)1)); map.put("type", new TField("type", (byte)8, (short)2)); } return map; }
@Override public TFieldIdEnum fieldForId(int i) { return null; }
@Override public boolean isSet(TFieldIdEnum tFieldIdEnum) { return false; }