在mule esb中的datamapper中流式传输

时间:2015-09-04 07:39:25

标签: streaming mule datamapper

我需要从一个大小在100MB-200MB的文件中获取数据(input.xml),并且需要根据某些逻辑写入四个不同的文件。

输入xml:

            <?xml version="1.0"?>
            <Orders>
                 <Order><OrderId>1</OrderId><Total>10</Total><Name>jon1</Name></Order>
                <Order><OrderId>2</OrderId><Total>20</Total><Name>jon2</Name></Order>
                <Order><OrderId>3</OrderId><Total>30</Total><Name>jon3</Name></Order>
                <Order><OrderId>4</OrderId><Total>40</Total><Name>jon4</Name></Order>
            <Orders>

逻辑是如果Total是1-10则写入file1,如果Total是11-20则写入file2 .....,

预期产出:

1 10 jon1 - &gt;写入file1

2 20 jon2 - &gt;写入file2

3 30 jon3 - &gt;写入file3

4 40 jon4 - &gt;写入file4

这里我已经在datamapper中启用了流式传输,但是我没有得到正确的输出。问题是我只得到一些重新编码到一个文件,在满足条件后应该进入该文件。

但是,如果我在datamapper中禁用流媒体按钮,它工作正常。由于有记录的湖泊,我必须使用流媒体选项。

还有其他配置datamapper来启用流媒体选项..?

请建议我。谢谢。,

1 个答案:

答案 0 :(得分:0)

如果没有更多关于你正在做什么的细节,很难看到问题。 不过,我认为这可能会帮助你尝试另一种方法。

数据映射器会将完整的XML文档加载到内存中,尽管您激活了流,但它必须这样做才能支持XPATH(它将完整的xml输入加载到DOM中)。 因此,如果您无法负担将200Mb文档加载到内存中,则需要尝试一种解决方法。

我之前做的是创建一个java组件,它在stax解析器的帮助下将输入流转换为迭代器。通过一个非常简单的实现,您可以编写一个迭代器来从流中提取以创建下一个元素(pojo,map,string ......)。在mule流程中,在“java组件”之后,您应该能够在其中使用“for-each”并使用“选择”并应用您的逻辑。

数据的简短示例:

#include <iostream>
#include <vector>

template <typename T>
size_t changes(const std::vector<T>& v)
{
    if (v.size() <= 2) return 0;
    size_t count = 0;
    enum { Increasing, Decreasing, Flat } last;
    last = v[0] < v[1] ? Increasing : v[1] < v[0] ? Decreasing : Flat;
    for (size_t i = 2; i < v.size(); ++i)
        if (v[i - 1] < v[i])
        {
            if (last == Decreasing) ++count;
            last = Increasing;
        }
        else if (v[i] < v[i - 1])
        {
            if (last == Increasing) ++count;
            last = Decreasing;
        }
    return count;
}

int main()
{
    std::cout << changes<int>({ 1, 3, 5, 4, 6 }) << '\n';
    std::cout << changes<int>({ 3, 3, 5, 4, 6 }) << '\n';
    std::cout << changes<int>({ 4, 3, 5, 4, 2, 2, 1 }) << '\n';
}

示例流程:

package tests;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class OrdersStreamIterator implements Iterator<Map<String,String>> {

    final static Log LOGGER = LogFactory.getLog(OrdersStreamIterator.class);

    final InputStream is;
    final XMLStreamReader xmlReader;

    boolean end = false;
    HashMap<String,String> next;

    public OrdersStreamIterator(InputStream is)
            throws XMLStreamException, FactoryConfigurationError {
        this.is = is;
        xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(is);
    }

    protected HashMap<String,String> _next() throws XMLStreamException {
        int event;
        HashMap<String,String> order = null;
        String orderChild = null;
        String orderChildValue = null;
        while (xmlReader.hasNext()) {
            event = xmlReader.getEventType();
            if (event == XMLStreamConstants.START_ELEMENT) {
                if (order==null) {
                    if (checkOrder()) {
                        order = new HashMap<String,String>();
                    }
                }
                else {
                    orderChild = xmlReader.getLocalName();
                }
            }
            else if (event == XMLStreamConstants.END_ELEMENT) {
                if (checkOrders()) {
                    end = true;
                    return null;
                }
                else if (checkOrder()) {
                    xmlReader.next();
                    return order;
                }
                else if (order!=null) {
                    order.put(orderChild, orderChildValue);
                    orderChild = null;
                    orderChildValue = null;
                }
            }
            else if (order!=null && orderChild!=null){
                switch (event) {
                case XMLStreamConstants.SPACE:
                case XMLStreamConstants.CHARACTERS:
                case XMLStreamConstants.CDATA:
                    int start = xmlReader.getTextStart();
                    int length = xmlReader.getTextLength();
                    if (orderChildValue==null) {
                        orderChildValue = new String(xmlReader.getTextCharacters(), start, length);
                    }
                    else {
                        orderChildValue += new String(xmlReader.getTextCharacters(), start, length);
                    }
                    break;
                }
            }
            xmlReader.next();
        }
        end = true;
        return null;
    }

    protected boolean checkOrder() {
        return "Order".equals(xmlReader.getLocalName());
    }

    protected boolean checkOrders() {
        return "Orders".equals(xmlReader.getLocalName());
    }

    @Override
    public boolean hasNext() {
        if (end) {
            return false;
        }
        else if (next==null) {
            try {
                next = _next();
            } catch (XMLStreamException e) {
                LOGGER.error(e.getMessage(), e);
                end = true;
            }
            return !end;
        }
        else {
            return true;
        }
    }


    @Override
    public Map<String,String> next() {
        if (hasNext()) {
            final HashMap<String,String> n = next;
            next = null;
            return n;
        }
        else {
            return null;
        }
    }


    @Override
    public void remove() {
        throw new RuntimeException("ReadOnly!");
    }

    // Test

    public static String dump(Map<String,String> o) {
        String s = "{";
        for (Entry<String,String> e : o.entrySet()) {
            if (s.length()>1) {
                s+=", ";
            }
            s+= "\"" + e.getKey() + "\" : \"" + e.getValue() + "\"";
        }
        return s + "}";
    }

    public static void main(String[] argv) throws XMLStreamException, FactoryConfigurationError {
        final InputStream is = OrdersStreamIterator.class.getClassLoader().getResourceAsStream("orders.xml");
        final OrdersStreamIterator i = new OrdersStreamIterator(is);
        while (i.hasNext()) {
            System.out.println(dump(i.next()));
        }
    }
}