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