aboutsummaryrefslogtreecommitdiffstats
path: root/messagebus/src/main/java/com/yahoo/messagebus/Reply.java
blob: e3359d1344c55b45402cbabb1ac0caa3ebd06360 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.messagebus;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;

/**
 * <p>A reply is a response to a message that has been sent throught the messagebus. No reply will ever exist without a
 * corresponding message. There are no error-replies defined, as errors can instead piggyback any reply by the {@link
 * #errors} member variable.</p>
 *
 * @author Simon Thoresen Hult
 */
public abstract class Reply extends Routable {

    private double retryDelay = -1.0;
    private Message msg = null;
    private List<Error> errors = new ArrayList<>();

    @Override
    public void swapState(Routable rhs) {
        super.swapState(rhs);
        if (rhs instanceof Reply) {
            Reply reply = (Reply)rhs;

            double retryDelay = this.retryDelay;
            this.retryDelay = reply.retryDelay;
            reply.retryDelay = retryDelay;

            Message msg = this.msg;
            this.msg = reply.msg;
            reply.msg = msg;

            List<Error> errors = this.errors;
            this.errors = reply.errors;
            reply.errors = errors;
        }
    }

    /**
     * <p>Returns the message to which this is a reply.</p>
     *
     * @return The message.
     */
    public Message getMessage() {
        return msg;
    }

    /**
     * <p>Sets the message to which this is a reply. Although it might seem very bogus to allow such an accessor, it is
     * necessary since we allow an empty constructor.</p>
     *
     * @param msg The message to which this is a reply.
     */
    public void setMessage(Message msg) {
        this.msg = msg;
    }

    /**
     * <p>Returns whether or not this reply contains any errors.</p>
     *
     * @return True if there are errors, false otherwise.
     */
    public boolean hasErrors() {
        return errors.size() > 0;
    }

    /**
     * <p>Returns whether or not this reply contains any fatal errors.</p>
     *
     * @return True if it contains fatal errors.
     */
    public boolean hasFatalErrors() {
        for (Error error : errors) {
            if (error.getCode() >= ErrorCode.FATAL_ERROR) {
                return true;
            }
        }
        return false;
    }

    /**
     * <p>Returns the error at the given position.</p>
     *
     * @param i The index of the error to return.
     * @return The error at the given index.
     */
    public Error getError(int i) {
        return errors.get(i);
    }

    /**
     * <p>Returns the number of errors that this reply contains.</p>
     *
     * @return The number of replies.
     */
    public int getNumErrors() {
        return errors.size();
    }

    /**
     * <p>Add an error to this reply. This method will also trace the error as long as there is any tracing
     * enabled.</p>
     *
     * @param error The error object to add.
     */
    public void addError(Error error) {
        errors.add(error);
        getTrace().trace(TraceLevel.ERROR, error.toString());
    }

    /**
     * <p>Returns the retry request of this reply. This can be set using {@link #setRetryDelay} and is an instruction to
     * the resender logic of message bus on how to perform the retry. If this value is anything other than a negative
     * number, it instructs the resender to disregard all configured resending attributes and instead act according to
     * this value.</p>
     *
     * @return The retry request.
     */
    public double getRetryDelay() {
        return retryDelay;
    }

    /**
     * <p>Sets the retry delay request of this reply. If this is a negative number, it will use the defaults configured
     * in the source session.</p>
     *
     * @param retryDelay The retry request.
     */
    public void setRetryDelay(double retryDelay) {
        this.retryDelay = retryDelay;
    }

    /**
     * Retrieves a (read only) stream of the errors in this reply
     */
    public Stream<Error> getErrors() {
        return errors.stream();
    }

    /**
     * Retrieves a set of integer error codes
     */
    public Set<Integer> getErrorCodes() {
        Set<Integer> errorCodes = new HashSet<>();
        for (Error error : errors) {
            errorCodes.add(error.getCode());
        }
        return errorCodes;
    }

}