/*
 * 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 org.apache.camel.itest.tx;

import javax.annotation.Resource;

import org.apache.camel.Exchange;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
import org.apache.camel.http.common.HttpOperationFailedException;
import org.apache.camel.spring.SpringRouteBuilder;
import org.apache.camel.spring.spi.SpringTransactionPolicy;
import org.apache.camel.test.AvailablePortFinder;

/**
 * Route that listen on a JMS queue and send a request/reply over http
 * before returning a response. Is transacted.
 * <p/>
 * Notice we use the SpringRouteBuilder that supports transacted
 * error handler.
 */
public class JmsToHttpWithOnExceptionRoute extends SpringRouteBuilder {
    protected static int counter;
    protected int port;

    @Resource(name = "PROPAGATION_REQUIRED")
    protected SpringTransactionPolicy required;

    protected final String nok = "<?xml version=\"1.0\"?><reply><status>nok</status></reply>";
    protected final String ok  = "<?xml version=\"1.0\"?><reply><status>ok</status></reply>";

    private final String noAccess = "<?xml version=\"1.0\"?><reply><status>Access denied</status></reply>";

    @Override
    public void configure() {
        port = AvailablePortFinder.getNextAvailable();

        // configure a global transacted error handler
        errorHandler(transactionErrorHandler(required));

        // if its a 404 then regard it as handled
        onException(HttpOperationFailedException.class).onWhen(new Predicate() {
            public boolean matches(Exchange exchange) {
                HttpOperationFailedException e = exchange.getException(HttpOperationFailedException.class);
                return e != null && e.getStatusCode() == 404;
            }
        }).handled(true).to("mock:JmsToHttpWithOnExceptionRoute404").transform(constant(noAccess));

        from("activemq:queue:JmsToHttpWithOnExceptionRoute")
            // must setup policy to indicate transacted route
            .policy(required)
            // send a request to http and get the response
            .to("http://localhost:" + port + "/sender")
            // convert the response to String so we can work with it and avoid streams only be readable once
            // as the http component will return data as a stream
            .convertBodyTo(String.class)
            // do a choice if the response is okay or not
            .choice()
                // do a xpath to compare if the status is NOT okay
                .when().xpath("/reply/status != 'ok'")
                    // as this is based on an unit test we use mocks to verify how many times we did rollback
                    .to("mock:JmsToHttpWithOnExceptionRoute")
                    // response is not okay so force a rollback
                    .rollback()
                .otherwise()
                // otherwise since its okay, the route ends and the response is sent back
                // to the original caller
            .end();

        // this is our http router
        from("jetty:http://localhost:" + port + "/sender").process(new Processor() {
            public void process(Exchange exchange) {
                // first hit is always a error code 500 to force the caller to retry
                if (counter++ < 1) {
                    // simulate http error 500
                    exchange.getMessage().setHeader(Exchange.HTTP_RESPONSE_CODE, 500);
                    exchange.getMessage().setBody("Damn some internal server error");
                    return;
                }

                String user = exchange.getIn().getHeader("user", String.class);
                if ("unknown".equals(user)) {
                    // no page for a unknown user
                    exchange.getMessage().setHeader(Exchange.HTTP_RESPONSE_CODE, 404);
                    exchange.getMessage().setBody("Page does not exists");
                    return;
                } else if ("guest".equals(user)) {
                    // not okay for guest user
                    exchange.getMessage().setBody(nok);
                    return;
                }

                exchange.getMessage().setBody(ok);
            }
        });
    }

}