org.apache.activemq.artemis.tests.integration.rest.util.RestMessageContext.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.activemq.artemis.tests.integration.rest.util.RestMessageContext.java

Source

/*
 * 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.activemq.artemis.tests.integration.rest.util;

import java.io.Closeable;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;

public abstract class RestMessageContext implements Closeable {

    public static final String KEY_MSG_CREATE = "msg-create";
    public static final String KEY_MSG_CREATE_ID = "msg-create-with-id";
    public static final String KEY_MSG_PULL = "msg-pull-consumers";
    public static final String KEY_MSG_PUSH = "msg-push-consumers";

    public static final String KEY_MSG_PULL_SUB = "msg-pull-subscriptions";
    public static final String KEY_MSG_PUSH_SUB = "msg-push-subscriptions";

    public static final String KEY_MSG_CREATE_NEXT = "msg-create-next";

    public static final String KEY_PULL_CONSUMERS_LOC = "pull-consumers-location";
    public static final String KEY_MSG_CONSUME_NEXT = "msg-consume-next";

    public static final String KEY_MSG_CONSUMER = "msg-consumer";
    public static final String KEY_MSG_ACK_NEXT = "msg-acknowledge-next";
    public static final String KEY_MSG_ACK = "msg-acknowledgement";

    protected RestAMQConnection connection;
    protected String destination;
    protected Map<String, String> contextMap = new HashMap<>();

    // consumer options
    protected boolean autoAck;
    protected boolean pushConsumer;

    public RestMessageContext(RestAMQConnection restAMQConnection, String dest) throws IOException {
        this(restAMQConnection, dest, true, false);
    }

    public RestMessageContext(RestAMQConnection restAMQConnection, String dest, boolean isAutoAck, boolean isPush)
            throws IOException {
        this.connection = restAMQConnection;
        this.destination = dest;
        this.autoAck = isAutoAck;
        this.pushConsumer = isPush;
        prepareSelf();
    }

    private void prepareSelf() throws IOException {
        String destLink = getDestLink();
        CloseableHttpResponse response = connection.request(destLink);
        int code = ResponseUtil.getHttpCode(response);
        if (code != 200) {
            System.out.println("failed to init " + destLink);
            System.out.println("reason: " + ResponseUtil.getDetails(response));
        }
        try {
            Header header = response.getFirstHeader(KEY_MSG_CREATE);
            contextMap.put(KEY_MSG_CREATE, header.getValue());
            header = response.getFirstHeader(KEY_MSG_CREATE_ID);
            contextMap.put(KEY_MSG_CREATE_ID, header.getValue());

            header = response.getFirstHeader(KEY_MSG_PULL);
            if (header != null) {
                contextMap.put(KEY_MSG_PULL, header.getValue());
            }
            header = response.getFirstHeader(KEY_MSG_PUSH);
            if (header != null) {
                contextMap.put(KEY_MSG_PUSH, header.getValue());
            }
            header = response.getFirstHeader(KEY_MSG_PULL_SUB);
            if (header != null) {
                contextMap.put(KEY_MSG_PULL_SUB, header.getValue());
            }
            header = response.getFirstHeader(KEY_MSG_PUSH_SUB);
            if (header != null) {
                contextMap.put(KEY_MSG_PUSH_SUB, header.getValue());
            }
        } finally {
            response.close();
        }
    }

    protected abstract String getDestLink();

    protected abstract String getPullConsumerUri();

    protected abstract String getPushLink(String pushTarget);

    public int postMessage(String content, String type) throws IOException {
        String postUri;
        String nextMsgUri = contextMap.get(KEY_MSG_CREATE_NEXT);
        if (nextMsgUri == null) {
            postUri = contextMap.get(KEY_MSG_CREATE);
        } else {
            postUri = nextMsgUri;
        }
        CloseableHttpResponse response = connection.post(postUri, type, content);
        int code = -1;
        try {
            code = ResponseUtil.getHttpCode(response);
            // check redirection
            if (code == 307) {
                Header redirLoc = response.getFirstHeader("Location");
                contextMap.put(KEY_MSG_CREATE_NEXT, redirLoc.getValue());
                code = postMessage(content, type);// do it again.
            } else if (code == 201) {
                Header header = response.getFirstHeader(KEY_MSG_CREATE_NEXT);
                contextMap.put(KEY_MSG_CREATE_NEXT, header.getValue());
            }
        } finally {
            response.close();
        }
        return code;
    }

    public abstract void initPullConsumers() throws IOException;

    public boolean acknowledgement(boolean ackValue) throws IOException {
        String ackUri = contextMap.get(KEY_MSG_ACK);
        if (ackUri != null) {
            CloseableHttpResponse response = connection.post(ackUri, "application/x-www-form-urlencoded",
                    "acknowledge=" + ackValue);
            int code = ResponseUtil.getHttpCode(response);
            if (code == 200) {
                contextMap.put(KEY_MSG_ACK_NEXT, response.getFirstHeader(KEY_MSG_ACK_NEXT).getValue());
            }
            return true;
        }
        return false;
    }

    public String pullMessage() throws IOException {
        String message = null;
        String msgPullUri = null;
        if (autoAck) {
            msgPullUri = contextMap.get(KEY_MSG_CONSUME_NEXT);
            if (msgPullUri == null) {
                initPullConsumers();
                msgPullUri = contextMap.get(KEY_MSG_CONSUME_NEXT);
            }
        } else {
            msgPullUri = contextMap.get(KEY_MSG_ACK_NEXT);
            if (msgPullUri == null) {
                initPullConsumers();
                msgPullUri = contextMap.get(KEY_MSG_ACK_NEXT);
            }
        }

        CloseableHttpResponse response = connection.post(msgPullUri);
        int code = ResponseUtil.getHttpCode(response);
        try {
            if (code == 200) {
                // success
                HttpEntity entity = response.getEntity();
                long len = entity.getContentLength();

                if (len != -1 && len < 1024000) {
                    message = EntityUtils.toString(entity);
                } else {
                    // drop message
                    System.err.println("Message too large, drop it " + len);
                }

                Header header = response.getFirstHeader(KEY_MSG_CONSUMER);
                contextMap.put(KEY_MSG_CONSUMER, header.getValue());

                if (!autoAck) {
                    header = response.getFirstHeader(KEY_MSG_ACK);
                    contextMap.put(KEY_MSG_ACK, header.getValue());
                } else {
                    header = response.getFirstHeader(KEY_MSG_CONSUME_NEXT);
                    contextMap.put(KEY_MSG_CONSUME_NEXT, header.getValue());
                }
            } else if (code == 503) {
                if (autoAck) {
                    contextMap.put(KEY_MSG_CONSUME_NEXT, response.getFirstHeader(KEY_MSG_CONSUME_NEXT).getValue());
                } else {
                    contextMap.put(KEY_MSG_ACK_NEXT, response.getFirstHeader(KEY_MSG_ACK_NEXT).getValue());
                }

                Header header = response.getFirstHeader("Retry-After");
                if (header != null) {
                    long retryDelay = Long.valueOf(response.getFirstHeader("Retry-After").getValue());
                    try {
                        Thread.sleep(retryDelay);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    message = pullMessage();
                }
            } else {
                throw new IllegalStateException("error: " + ResponseUtil.getDetails(response));
            }
        } finally {
            response.close();
        }

        return message;
    }

    @Override
    public void close() {
        String consumerUri = contextMap.get(KEY_MSG_CONSUMER);
        if (consumerUri != null) {
            try {
                connection.delete(consumerUri);
                contextMap.remove(KEY_MSG_CONSUMER);
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void setUpPush(String pushTarget) throws Exception {
        String pushLink = this.contextMap.get(KEY_MSG_PUSH);
        String pushRegXml = "<push-registration>" + "<link rel=\"destination\" href=\""
                + this.connection.getTargetUri() + this.getPushLink(pushTarget) + "\"/>" + "</push-registration>";

        CloseableHttpResponse response = connection.post(pushLink, "application/xml", pushRegXml);
        int code = ResponseUtil.getHttpCode(response);
        try {
            if (code != 201) {
                System.out.println("Failed to push " + pushRegXml);
                System.out.println("Location: " + pushLink);
                throw new Exception("Failed to register push " + ResponseUtil.getDetails(response));
            }
        } finally {
            response.close();
        }
    }
}