3
votes

I am new to Anypoint Studio and I am trying to create a flow that will have an HTTP connector and an endpoint and when a user invokes the http endpoint then the application will load the contents of an XML file, will convert then to JSON and will return the JSON back in the HTTP Response.

My flow configuration looks like this

<flow name="test-flow">
        <http:listener config-ref="HttpListenerConfiguration" path="/read" allowedMethods="POST" doc:name="HTTP">
            <http:response-builder statusCode="200">
                <http:header headerName="Content-Type" value="application/json"/>
            </http:response-builder>
        </http:listener>
        <file:inbound-endpoint path="xml/test.xml" responseTimeout="10000" doc:name="File"/>
        <mulexml:xml-to-object-transformer returnClass="org.mule.examples.Catalog" doc:name="XML to Object"/>
        <json:object-to-json-transformer sourceClass="org.mule.examples.Catalog" doc:name="Object to JSON"/>
    </flow>

Of course it doesn't work. I get a

SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'file:inbound-endpoint'. One of '{"http://www.mulesoft.org/schema/mule/core":abstract-message-processor, "http://www.mulesoft.org/schema/mule/core":abstract-outbound-endpoint, "http://www.mulesoft.org/schema/mule/core":abstract-mixed-content-message-processor, "http://www.mulesoft.org/schema/mule/core":response}' is expected.

which I assume is coming from the fact that <file:inbound-endpoint...> needs to be as a source in the flow.

Any suggestions on how can I read a file after an HTTP endpoint is invoked?

Thanks

6

6 Answers

2
votes

As you correctly assumed, file:inbound-endpoint can only act as a message source. Thus to achieve what you want you can use the mule module requester. HTH.

1
votes

Try the requester module. It will allow you to load the file at any point in the flow. You can read more about it in this blogpost.

1
votes

Also you can use XML to Json inbuilt transformer in to convert it to a Json object.

<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="test-flow1">
    <http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
    <json:xml-to-json-transformer doc:name="XML to JSON"/>
    <logger message="#[message.payload]" level="INFO" doc:name="Logger"/>
</flow>
0
votes

If the XML file is on the classpath, you might try <parse-template location="xml/test.xml"> instead of your <file:inbound-endpoint />

The parse-template processor comes in handy surprisingly often. The User's Guide also has a nice reference for it.

0
votes

You can also write a java component to read the content of the file and use that component in the flow.

Example:

public class FileReaderComponent implements Callable, Initialisable {

private String filePath;

public String getFilePath() {
    return filePath;
}

public void setFilePath(String filePath) {
    this.filePath = filePath;
}

@Override
public void initialise() throws InitialisationException {
    if (filePath == null || filePath.equals("")) {
        throw new InitialisationException(MessageFactory.createStaticMessage("FilePath property has to be set"), this);
    }
}
@Override
public Object onCall(MuleEventContext eventContext) throws Exception {

    BufferedReader in = null;
    try {
        in = new BufferedReader(new FileReader(new File(filePath)));
    } catch (Exception e) {
        //Handle Exception
    }

    StringBuilder content = new StringBuilder();

    try {

        String line;
        while ((line = in.readLine()) != null) {
          content.append(line);

        } 
    }catch (Exception e) {
        //Handle Exception
    } finally {
        in.close();
    }


    return content.toString();
}

}

0
votes

As many suggested in above, you can use java component or some kind of parse template.

We also had same kind of requirement , we used the expression component to read the file from particular location