23
23
24
24
import io .objectbox .BoxStore ;
25
25
import io .objectbox .annotation .apihint .Experimental ;
26
+ import io .objectbox .flatbuffers .FlatBufferBuilder ;
27
+ import io .objectbox .sync .Credentials ;
26
28
import io .objectbox .sync .SyncCredentials ;
29
+ import io .objectbox .sync .SyncCredentialsToken ;
27
30
import io .objectbox .sync .listener .SyncChangeListener ;
28
31
29
32
/**
30
33
* Creates a {@link SyncServer} and allows to set additional configuration.
31
34
*/
32
- @ SuppressWarnings ({"unused" , "UnusedReturnValue" , "WeakerAccess" })
35
+ @ SuppressWarnings ({"unused" , "UnusedReturnValue" })
33
36
@ Experimental
34
37
public class SyncServerBuilder {
35
38
36
39
final BoxStore boxStore ;
37
40
final String url ;
38
- final List <SyncCredentials > credentials = new ArrayList <>();
41
+ private final List <SyncCredentialsToken > credentials = new ArrayList <>();
39
42
final List <PeerInfo > peers = new ArrayList <>();
40
43
41
- @ Nullable String certificatePath ;
44
+ private @ Nullable String certificatePath ;
42
45
SyncChangeListener changeListener ;
43
46
44
47
public SyncServerBuilder (BoxStore boxStore , String url , SyncCredentials authenticatorCredentials ) {
@@ -55,7 +58,14 @@ public SyncServerBuilder(BoxStore boxStore, String url, SyncCredentials authenti
55
58
authenticatorCredentials (authenticatorCredentials );
56
59
}
57
60
61
+ /**
62
+ * Sets the path to a directory that contains a cert.pem and key.pem file to use to establish encrypted
63
+ * connections.
64
+ * <p>
65
+ * Use the "wss://" protocol for the server URL to turn on encrypted connections.
66
+ */
58
67
public SyncServerBuilder certificatePath (String certificatePath ) {
68
+ checkNotNull (certificatePath , "Certificate path must not be null" );
59
69
this .certificatePath = certificatePath ;
60
70
return this ;
61
71
}
@@ -68,7 +78,11 @@ public SyncServerBuilder certificatePath(String certificatePath) {
68
78
*/
69
79
public SyncServerBuilder authenticatorCredentials (SyncCredentials authenticatorCredentials ) {
70
80
checkNotNull (authenticatorCredentials , "Authenticator credentials must not be null." );
71
- credentials .add (authenticatorCredentials );
81
+ if (!(authenticatorCredentials instanceof SyncCredentialsToken )) {
82
+ throw new IllegalArgumentException ("Sync credentials of type " + authenticatorCredentials .getType ()
83
+ + " are not supported" );
84
+ }
85
+ credentials .add ((SyncCredentialsToken ) authenticatorCredentials );
72
86
return this ;
73
87
}
74
88
@@ -94,7 +108,11 @@ public SyncServerBuilder peer(String url) {
94
108
* Adds a server peer, to which this server should connect to as a client using the given credentials.
95
109
*/
96
110
public SyncServerBuilder peer (String url , SyncCredentials credentials ) {
97
- peers .add (new PeerInfo (url , credentials ));
111
+ if (!(credentials instanceof SyncCredentialsToken )) {
112
+ throw new IllegalArgumentException ("Sync credentials of type " + credentials .getType ()
113
+ + " are not supported" );
114
+ }
115
+ peers .add (new PeerInfo (url , (SyncCredentialsToken ) credentials ));
98
116
return this ;
99
117
}
100
118
@@ -125,4 +143,100 @@ private void checkNotNull(Object object, String message) {
125
143
}
126
144
}
127
145
146
+ /**
147
+ * From this configuration, builds a {@link SyncServerOptions} FlatBuffer and returns it as bytes.
148
+ * <p>
149
+ * Clears configured credentials, they can not be used again after this returns.
150
+ */
151
+ byte [] buildSyncServerOptions () {
152
+ FlatBufferBuilder fbb = new FlatBufferBuilder ();
153
+ // Always put values, even if they match the default values (defined in the generated classes)
154
+ fbb .forceDefaults (true );
155
+
156
+ // Serialize non-integer values first to get their offset
157
+ int urlOffset = fbb .createString (url );
158
+ int certificatePathOffset = 0 ;
159
+ if (certificatePath != null ) {
160
+ certificatePathOffset = fbb .createString (certificatePath );
161
+ }
162
+ int authenticationMethodsOffset = buildAuthenticationMethods (fbb );
163
+ int clusterPeersVectorOffset = buildClusterPeers (fbb );
164
+
165
+ // TODO Support remaining options
166
+ // After collecting all offsets, create options
167
+ SyncServerOptions .startSyncServerOptions (fbb );
168
+ SyncServerOptions .addUrl (fbb , urlOffset );
169
+ SyncServerOptions .addAuthenticationMethods (fbb , authenticationMethodsOffset );
170
+ // SyncServerOptions.addSyncFlags();
171
+ // SyncServerOptions.addSyncServerFlags();
172
+ if (certificatePathOffset > 0 ) {
173
+ SyncServerOptions .addCertificatePath (fbb , certificatePathOffset );
174
+ }
175
+ // SyncServerOptions.addWorkerThreads();
176
+ // SyncServerOptions.addHistorySizeMaxKb();
177
+ // SyncServerOptions.addHistorySizeTargetKb();
178
+ // SyncServerOptions.addAdminUrl();
179
+ // SyncServerOptions.addAdminThreads();
180
+ // SyncServerOptions.addClusterId();
181
+ if (clusterPeersVectorOffset > 0 ) {
182
+ SyncServerOptions .addClusterPeers (fbb , clusterPeersVectorOffset );
183
+ }
184
+ // SyncServerOptions.addClusterFlags();
185
+ int offset = SyncServerOptions .endSyncServerOptions (fbb );
186
+ fbb .finish (offset );
187
+
188
+ return fbb .sizedByteArray ();
189
+ }
190
+
191
+ private int buildAuthenticationMethods (FlatBufferBuilder fbb ) {
192
+ int [] credentialsOffsets = new int [credentials .size ()];
193
+ for (int i = 0 ; i < credentials .size (); i ++) {
194
+ credentialsOffsets [i ] = buildCredentials (fbb , credentials .get (i ));
195
+ }
196
+ return SyncServerOptions .createAuthenticationMethodsVector (fbb , credentialsOffsets );
197
+ }
198
+
199
+ private int buildCredentials (FlatBufferBuilder fbb , SyncCredentialsToken tokenCredentials ) {
200
+ int tokenBytesOffset = 0 ;
201
+ byte [] tokenBytes = tokenCredentials .getTokenBytes ();
202
+ if (tokenBytes != null ) {
203
+ tokenBytesOffset = Credentials .createBytesVector (fbb , tokenBytes );
204
+ }
205
+
206
+ Credentials .startCredentials (fbb );
207
+ // TODO Will this still be necessary?
208
+ // The core API used by nativeSetAuthenticator only supports the NONE and SHARED_SECRET types
209
+ // (however, protocol v3 versions do also add SHARED_SECRET_SIPPED if SHARED_SECRET is given).
210
+ final SyncCredentials .CredentialsType type = tokenCredentials .getType () == SyncCredentials .CredentialsType .SHARED_SECRET_SIPPED
211
+ ? SyncCredentials .CredentialsType .SHARED_SECRET
212
+ : tokenCredentials .getType ();
213
+ Credentials .addType (fbb , type .id );
214
+ if (tokenBytesOffset > 0 ) {
215
+ Credentials .addBytes (fbb , tokenBytesOffset );
216
+ }
217
+ int credentialsOffset = Credentials .endCredentials (fbb );
218
+
219
+ tokenCredentials .clear (); // Clear immediately, not needed anymore.
220
+
221
+ return credentialsOffset ;
222
+ }
223
+
224
+ private int buildClusterPeers (FlatBufferBuilder fbb ) {
225
+ if (peers .isEmpty ()) {
226
+ return 0 ;
227
+ }
228
+
229
+ int [] peersOffsets = new int [peers .size ()];
230
+ for (int i = 0 ; i < peers .size (); i ++) {
231
+ PeerInfo peer = peers .get (i );
232
+
233
+ int urlOffset = fbb .createString (peer .url );
234
+ int credentialsOffset = buildCredentials (fbb , peer .credentials );
235
+
236
+ peersOffsets [i ] = ClusterPeerConfig .createClusterPeerConfig (fbb , urlOffset , credentialsOffset );
237
+ }
238
+
239
+ return SyncServerOptions .createClusterPeersVector (fbb , peersOffsets );
240
+ }
241
+
128
242
}
0 commit comments