Skip to content

Commit d23405c

Browse files
author
Narine Cholakyan
committed
Merge branch 'master' into maven-publish
* master: Added error handling on login Added build status image Added tests Build only on master and prs specify jdk for travis testing travis.yml
2 parents be01c8d + f0608b1 commit d23405c

File tree

10 files changed

+210
-72
lines changed

10 files changed

+210
-72
lines changed

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
language: java
2+
jdk:
3+
- oraclejdk8
4+
branches:
5+
only:
6+
- master

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Contextual Sync
22

3+
[![Build Status - Master](https://travis-ci.org/csync/csync-java.svg?branch=master)](https://travis-ci.org/csync/csync-java)
4+
[![License][license-svg]][license-link]
5+
6+
[license-svg]: https://img.shields.io/hexpm/l/plug.svg
7+
[license-link]: https://github.com/csync/csync-server/blob/master/LICENSE
8+
39
Contextual Sync (CSync) is an open source, real-time, continuous data synchronization service for building modern applications. The CSync data store is organized with key/values where keys have a hierarchical structure. Clients can obtain the current value for a key and any subsequent updates by listening on the key. Updates are delivered to all online clients in near-real time. Clients can also listen on a key pattern where some components contain wildcards.
410

511
## Keys

src/main/java/com/ibm/csync/CSync.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public static class Builder {
121121
private Builder() {}
122122

123123
public Builder defaultBlockingTimeout(final Timeout timeout) {
124-
if (timeout == null) throw new IllegalArgumentException();
124+
if (timeout == null || timeout.ms < 0) throw new IllegalArgumentException();
125125
this.defaultBlockingTimeout = timeout;
126126
return this;
127127
}

src/main/java/com/ibm/csync/impl/Transport.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class Transport implements WebSocketListener {
5656
private Promise<WebSocket> socketPromise = null;
5757
private Futur<WebSocket> socketFutur = null;
5858
private final Executor sendExec = Executors.newSingleThreadExecutor();
59-
59+
private WebSocket loginWebSocket = null; //Needs to be stored so that we callback when we are sure auth succeeded
6060
// TODO: handle concurrency
6161
//private final Set<Callback<WebSocket>> waitingForSocket = ConcurrentHashMap.newKeySet();
6262
private final Map<Long, Promise<Envelope>> waitingForResponse = Collections.synchronizedMap(new WeakHashMap<>());
@@ -115,18 +115,16 @@ public synchronized <T> Futur<T> rpc(final String kind, final Object request, C
115115

116116
@Override
117117
public synchronized void onOpen(WebSocket webSocket, Response response) {
118-
final Promise<WebSocket> thePromise = socketPromise;
119-
socketPromise = null;
120-
121-
if (thePromise == null) {
118+
if (socketPromise == null) {
122119
try {
123120
webSocket.close(0,"not needed");
124121
} catch (IOException e) {
125122
tracer.onError(e, "onOpen");
126123
}
127-
} else {
128-
thePromise.set(null, webSocket);
129124
}
125+
//set login websocket to callback if it isn't already set
126+
if(loginWebSocket == null)
127+
loginWebSocket = webSocket;
130128
}
131129

132130
@Override
@@ -159,8 +157,24 @@ public void onMessage(final ResponseBody message_) throws IOException {
159157
final Connect.Response r = gson.fromJson(env.payload, Connect.Response.class);
160158
// TODO: check uuid
161159
tracer.onConnect(r);
160+
161+
//Auth was successful and we are waiting on the callback, so send it
162+
if(loginWebSocket != null ) {
163+
final Promise<WebSocket> thePromise = socketPromise;
164+
socketPromise = null;
165+
thePromise.set(null, loginWebSocket);
166+
loginWebSocket = null;
167+
}
168+
162169
} else {
163170
tracer.onError(new Exception(),"unknown kind %s",env);
171+
//If we failed login and are waiting on a callback, send a failure.
172+
if(loginWebSocket != null){
173+
final Promise<WebSocket> thePromise = socketPromise;
174+
socketPromise = null;
175+
thePromise.set(new Exception("Auth failed"),loginWebSocket);
176+
loginWebSocket = null;
177+
}
164178
}
165179
}
166180
}
@@ -175,9 +189,11 @@ public synchronized void onClose(int code, String reason) {
175189
final Promise<WebSocket> thePromise = socketPromise;
176190
socketPromise = null;
177191
socketFutur = null;
192+
loginWebSocket = null;
178193
if (thePromise != null) {
179194
thePromise.set(new Exception(reason),null);
180195
}
196+
181197
}
182198

183199
}

src/test/java/com/ibm/csync/AdvanceTestsIT.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,14 @@
2222
import org.junit.Before;
2323
import org.junit.Test;
2424

25+
import java.io.Closeable;
2526
import java.util.ArrayList;
2627
import java.util.UUID;
2728
import java.util.concurrent.CompletableFuture;
2829
import java.util.concurrent.TimeUnit;
2930

3031
import static org.junit.Assert.assertTrue;
3132

32-
/**
33-
* Created by thomasboop on 3/13/17.
34-
*/
3533
public class AdvanceTestsIT {
3634

3735
CSync csync;
@@ -67,25 +65,26 @@ public void testSimpleAdvance() throws Exception{
6765
String uuid = UUID.randomUUID().toString();
6866

6967

70-
CompletableFuture<String> future = new CompletableFuture<>();
68+
CompletableFuture<Boolean> future = new CompletableFuture<>();
7169
csync.blocking.pub("tests.java." + uuid + ".a",String.valueOf(0));
7270
csync.blocking.pub("tests.java." + uuid + ".a.b",String.valueOf(0));
7371
csync.blocking.pub("tests.java." + uuid + ".a.b.c",String.valueOf(0));
7472
csync.blocking.pub("tests.java." + uuid + ".a.b.c.d",String.valueOf(0));
75-
csync.listen(
73+
Closeable listener = csync.listen(
7674
Key.of("tests.java."+uuid+".#"),
7775
data -> {
7876
totalCount++;
7977
if (totalCount == 200){
80-
future.complete("pass");
78+
future.complete(true);
8179
}
8280

8381
int value = Integer.parseInt(data.data);
8482
if(value < 50){
8583
csync.blocking.pub(data.key.string,String.valueOf(value+1));
8684
}
8785
});
88-
assertTrue(future.get(30, TimeUnit.SECONDS).equals("pass"));
86+
assertTrue(future.get(30, TimeUnit.SECONDS));
87+
listener.close();
8988
keysToCleanup.add("tests.java." + uuid + ".a");
9089
keysToCleanup.add("tests.java." + uuid + ".a.b");
9190
keysToCleanup.add("tests.java." + uuid + ".a.b.c");
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
*
3+
* * Copyright IBM Corporation 2016-2017
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * http://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package com.ibm.csync;
20+
21+
import org.junit.Test;
22+
import static org.junit.Assert.*;
23+
24+
public class BuilderTestsIT {
25+
26+
@Test(expected=IllegalArgumentException.class)
27+
public void testNullTimeout() throws Exception{
28+
CSync csync = CSync.builder()
29+
.defaultBlockingTimeout(null)
30+
.build();
31+
fail("Was able to build with no timeout");
32+
}
33+
34+
@Test(expected=IllegalArgumentException.class)
35+
public void testNullWorkers() throws Exception{
36+
CSync csync = CSync.builder()
37+
.workers(null)
38+
.build();
39+
fail("Was able to build with null workers");
40+
}
41+
42+
@Test(expected=IllegalArgumentException.class)
43+
public void testBadWorkers() throws Exception{
44+
CSync csync = CSync.builder()
45+
.defaultBlockingTimeout(Timeout.of(-5))
46+
.build();
47+
fail("Was able to build with negative timeout");
48+
}
49+
50+
@Test(expected=IllegalArgumentException.class)
51+
public void testBadPort() throws Exception{
52+
CSync csync = CSync.builder()
53+
.port(-5)
54+
.build();
55+
fail("Was able to build with negative port");
56+
}
57+
58+
59+
}

src/test/java/com/ibm/csync/ConnectTestsIT.java

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818

1919
package com.ibm.csync;
2020

21-
import org.junit.After;
22-
import org.junit.Before;
2321
import org.junit.Test;
2422

2523
import java.util.concurrent.CompletableFuture;
@@ -47,85 +45,87 @@ public void guestLogin() {
4745
}
4846
}
4947

50-
/* @Test
51-
public void badProvider() throws Exception{
52-
CompletableFuture<String> future = new CompletableFuture<>();
53-
try {
54-
final CSync csync = CSync.builder()
55-
.token("demoToken")
56-
.provider("demozzzzzzzz")
57-
.sessionId("xyz")
58-
.build();
59-
csync.pub("a","b");
60-
61-
}
62-
catch (Exception e){
63-
future.complete("pass");
64-
}
65-
assertTrue(future.get(20, TimeUnit.SECONDS).equals("pass"));
66-
}*/
67-
6848
@Test
69-
public void badProvider() {
49+
public void badProvider() throws Exception{
50+
CompletableFuture<Boolean> future = new CompletableFuture<>();
7051
try {
7152
final CSync csync = CSync.builder()
72-
.token("faketokendoesntwork")
73-
.provider("demozz")
53+
.token(System.getenv("CSYNC_DEMO_TOKEN"))
54+
.provider("thisisafakeprovider")
55+
.host(System.getenv("CSYNC_HOST"))
56+
.port(Integer.parseInt(System.getenv("CSYNC_PORT")))
7457
.build();
7558

7659
csync.blocking.pub("a","a");
77-
fail("Test failed, was able to pub with a bad guest login");
60+
fail("should have been able to do a blocking pub with a bad login");
7861

7962
}
8063
catch (Exception e){
64+
future.complete(true);
8165
}
66+
assertTrue(future.get(10, TimeUnit.SECONDS));
8267
}
8368

8469
@Test
85-
public void badGuestLogin() {
70+
public void badGuestLogin() throws Exception{
71+
CompletableFuture<Boolean> future = new CompletableFuture<>();
8672
try {
8773
final CSync csync = CSync.builder()
88-
.token("faketokendoesntwork")
89-
.provider("demo")
74+
.token("thistokenshouldfail")
75+
.provider(System.getenv("CSYNC_DEMO_PROVIDER"))
76+
.host(System.getenv("CSYNC_HOST"))
77+
.port(Integer.parseInt(System.getenv("CSYNC_PORT")))
9078
.build();
9179

9280
csync.blocking.pub("a","a");
93-
fail("Test failed, was able to pub with a bad guest login");
81+
fail("should have been able to do a blocking pub with a bad login");
9482

9583
}
9684
catch (Exception e){
85+
future.complete(true);
9786
}
87+
assertTrue(future.get(10, TimeUnit.SECONDS));
9888
}
9989

10090
@Test
101-
public void badFacebookLogin() {
91+
public void badFacebookLogin() throws Exception{
92+
CompletableFuture<Boolean> future = new CompletableFuture<>();
10293
try {
10394
final CSync csync = CSync.builder()
104-
.token("iamnotarealfacebooktoken")
95+
.token("thisisafaketoken")
10596
.provider("facebook")
97+
.host(System.getenv("CSYNC_HOST"))
98+
.port(Integer.parseInt(System.getenv("CSYNC_PORT")))
10699
.build();
107100

108101
csync.blocking.pub("a","a");
109-
fail("Test failed, was able to pub with a bad facebook token");
102+
fail("should have been able to do a blocking pub with a bad login");
110103

111104
}
112105
catch (Exception e){
106+
future.complete(true);
113107
}
108+
assertTrue(future.get(10, TimeUnit.SECONDS));
114109
}
115110

116111
@Test
117-
public void badGoogleLogin() {
112+
public void badGoogleLogin() throws Exception{
113+
CompletableFuture<Boolean> future = new CompletableFuture<>();
118114
try {
119115
final CSync csync = CSync.builder()
120-
.token("iamnotarealgoogletoken")
116+
.token("thisisafaketoken")
121117
.provider("google")
118+
.host(System.getenv("CSYNC_HOST"))
119+
.port(Integer.parseInt(System.getenv("CSYNC_PORT")))
122120
.build();
123121

124122
csync.blocking.pub("a","a");
125-
fail("Test failed, was able to pub with a bad google token");
123+
fail("should have been able to do a blocking pub with a bad login");
126124

127125
}
128126
catch (Exception e){
127+
future.complete(true);
129128
}
129+
assertTrue(future.get(10, TimeUnit.SECONDS));
130130
}
131131
}

src/test/java/com/ibm/csync/KeyTests.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,6 @@ public void testMatches() {
5757
nomatch("a.b","x.*");
5858
}
5959

60-
//Test the max length of the key, this should fail.
61-
@Test
62-
public void testMaxLength(){
63-
Key testKey = Key.of("a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z");
64-
//comment back in when fixed
65-
//assertTrue(testKey.string.equals(""));
66-
}
67-
68-
//Tests that keys created two different ways are seen as equal
69-
@Test
7060
public void testInitializer(){
7161
Key keyOne = Key.of("a","b","c");
7262
Key keyTwo = Key.of("a.b.c");

src/test/java/com/ibm/csync/PubTestsIT.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,18 @@ public void testSimpleBlockingPub() {
7373
@Test
7474
public void testSimpleNonBlockingPub() throws Exception {
7575
String uuid = UUID.randomUUID().toString();
76-
CompletableFuture<String> future = new CompletableFuture<>();
76+
CompletableFuture<Boolean> future = new CompletableFuture<>();
7777
try {
7878
csync.pub("tests.java."+uuid+".a.b.c","abc", (error, vts) -> {
7979
if (error == null && vts > 0)
80-
future.complete("pass");
80+
future.complete(true);
8181
}
8282
);
8383
}
8484
catch (Exception e) {
8585
fail("Failed to send a nonblocking pub");
8686
}
87-
String pass = future.get(10,TimeUnit.SECONDS);
88-
assertTrue(pass.equals("pass"));
87+
assertTrue(future.get(10,TimeUnit.SECONDS));
8988
keysToCleanup.add("tests.java."+uuid+".a.b.c");
9089
}
9190

@@ -103,4 +102,16 @@ public void testDeleteWildcard() throws Exception{
103102
keysToCleanup.add("tests.java."+uuid+".e.e");
104103

105104
}
105+
106+
@Test
107+
public void testPubWithTooManyParts() throws Exception{
108+
CompletableFuture<Boolean> future = new CompletableFuture<>();
109+
try {
110+
csync.blocking.pub("tests.java.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z", "a");
111+
}
112+
catch (Exception e){
113+
future.complete(true);
114+
}
115+
assertTrue(future.get(10,TimeUnit.SECONDS));
116+
}
106117
}

0 commit comments

Comments
 (0)