6bae647cb7a43a1ef000961b48333104f7f6857a
[controller.git] / opendaylight / md-sal / sal-clustering-commons / src / main / java / org / opendaylight / controller / cluster / messaging / SliceOptions.java
1 /*
2  * Copyright (c) 2017 Inocybe Technologies and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.messaging;
9
10 import akka.actor.ActorRef;
11 import akka.actor.ActorSelection;
12 import com.google.common.base.Preconditions;
13 import java.io.Serializable;
14 import java.util.function.Consumer;
15 import org.opendaylight.controller.cluster.io.FileBackedOutputStream;
16 import org.opendaylight.controller.cluster.io.FileBackedOutputStreamFactory;
17 import org.opendaylight.yangtools.concepts.Identifier;
18
19 /**
20  * Options for slicing a message with {@link MessageSlicer#slice(SliceOptions)}.
21  *
22  * @author Thomas Pantelis
23  */
24 public final class SliceOptions {
25     private final Builder builder;
26
27     private SliceOptions(final Builder builder) {
28         this.builder = builder;
29     }
30
31     public Identifier getIdentifier() {
32         return builder.identifier;
33     }
34
35     public FileBackedOutputStream getFileBackedStream() {
36         return builder.fileBackedStream;
37     }
38
39     public Serializable getMessage() {
40         return builder.message;
41     }
42
43     public ActorRef getSendToRef() {
44         return builder.sendToRef;
45     }
46
47     public ActorSelection getSendToSelection() {
48         return builder.sendToSelection;
49     }
50
51     public ActorRef getReplyTo() {
52         return builder.replyTo;
53     }
54
55     public Consumer<Throwable> getOnFailureCallback() {
56         return builder.onFailureCallback;
57     }
58
59     /**
60      * Returns a new Builder for creating MessageSlicer instances.
61      *
62      * @return a Builder instance
63      */
64     public static Builder builder() {
65         return new Builder();
66     }
67
68     public static class Builder {
69         private Identifier identifier;
70         private FileBackedOutputStream fileBackedStream;
71         private Serializable message;
72         private ActorRef sendToRef;
73         private ActorSelection sendToSelection;
74         private ActorRef replyTo;
75         private Consumer<Throwable> onFailureCallback;
76         private boolean sealed;
77
78         /**
79          * Sets the identifier of the component to slice.
80          *
81          * @param newIdentifier the identifier
82          * @return this Builder
83          */
84         public Builder identifier(final Identifier newIdentifier) {
85             checkSealed();
86             identifier = newIdentifier;
87             return this;
88         }
89
90         /**
91          * Sets the {@link FileBackedOutputStream} containing the message data to slice.
92          *
93          * @param newFileBackedStream the {@link FileBackedOutputStream}
94          * @return this Builder
95          */
96         public Builder fileBackedOutputStream(final FileBackedOutputStream newFileBackedStream) {
97             checkSealed();
98             fileBackedStream = newFileBackedStream;
99             return this;
100         }
101
102         /**
103          * Sets the message to slice. The message is first serialized to a {@link FileBackedOutputStream}. If the
104          * message doesn't need to be sliced, ie its serialized size is less than the maximum message slice size, then
105          * the original message is sent. Otherwise the first message slice is sent.
106          *
107          * <p>
108          * <b>Note:</b> a {@link FileBackedOutputStreamFactory} must be set in the {@link MessageSlicer}.
109          *
110          * @param newMessage the message
111          * @param <T> the Serializable message type
112          * @return this Builder
113          */
114         public <T extends Serializable> Builder message(final T newMessage) {
115             checkSealed();
116             message = newMessage;
117             return this;
118         }
119
120         /**
121          * Sets the reference of the actor to which to send the message slices.
122          *
123          * @param sendTo the ActorRef
124          * @return this Builder
125          */
126         public Builder sendTo(final ActorRef sendTo) {
127             checkSealed();
128             sendToRef = sendTo;
129             return this;
130         }
131
132         /**
133          * Sets the ActorSelection to which to send the message slices.
134          *
135          * @param sendTo the ActorSelection
136          * @return this Builder
137          */
138         public Builder sendTo(final ActorSelection sendTo) {
139             checkSealed();
140             sendToSelection = sendTo;
141             return this;
142         }
143
144         /**
145          * Sets the reference of the actor to which message slice replies should be sent. The actor should
146          * forward the replies to the {@link MessageSlicer#handleMessage(Object)} method.
147          *
148          * @param newReplyTo the ActorRef
149          * @return this Builder
150          */
151         public Builder replyTo(final ActorRef newReplyTo) {
152             checkSealed();
153             replyTo = newReplyTo;
154             return this;
155         }
156
157         /**
158          * Sets the callback to be notified of failure.
159          *
160          * @param newOnFailureCallback the callback
161          * @return this Builder
162          */
163         public Builder onFailureCallback(final Consumer<Throwable> newOnFailureCallback) {
164             checkSealed();
165             onFailureCallback = newOnFailureCallback;
166             return this;
167         }
168
169         /**
170          * Builds a new SliceOptions instance.
171          *
172          * @return a new SliceOptions
173          */
174         public SliceOptions build() {
175             sealed = true;
176
177             Preconditions.checkNotNull(identifier, "identifier must be set");
178             Preconditions.checkNotNull(replyTo, "replyTo must be set");
179             Preconditions.checkNotNull(onFailureCallback, "onFailureCallback must be set");
180             Preconditions.checkState(fileBackedStream == null || message == null,
181                     "Only one of message and fileBackedStream can be set");
182             Preconditions.checkState(!(fileBackedStream == null && message == null),
183                     "One of message and fileBackedStream must be set");
184             Preconditions.checkState(sendToRef == null || sendToSelection == null,
185                     "Only one of sendToRef and sendToSelection can be set");
186             Preconditions.checkState(!(sendToRef == null && sendToSelection == null),
187                     "One of sendToRef and sendToSelection must be set");
188
189             return new SliceOptions(this);
190         }
191
192         protected void checkSealed() {
193             Preconditions.checkState(!sealed, "Builder is already sealed - further modifications are not allowed");
194         }
195     }
196 }