Skip to content

Commit a5c2c82

Browse files
authored
Feature/min replication factor (#282)
* added minReplicationFactor entity * added test for minReplicationFactor * added VPackSerializer, VPackDeserializer & VPackDriverModule * started work on graph attribute minReplicationFactor * fixed graph test * changelog
1 parent a0fd2bc commit a5c2c82

File tree

11 files changed

+433
-260
lines changed

11 files changed

+433
-260
lines changed

ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- added minReplicationAttribute for collections and graphs
12+
913
## [5.0.7] - 2019-07-19
1014

1115
### Fixed

src/main/java/com/arangodb/entity/CollectionPropertiesEntity.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@ public class CollectionPropertiesEntity extends CollectionEntity {
3838
private Integer numberOfShards;
3939
private Collection<String> shardKeys;
4040
private final ReplicationFactor replicationFactor;
41+
private final MinReplicationFactor minReplicationFactor;
4142

4243
private String shardingStrategy; // cluster option
4344
private String smartJoinAttribute; // enterprise option
4445

4546
public CollectionPropertiesEntity() {
4647
super();
4748
replicationFactor = new ReplicationFactor();
49+
minReplicationFactor = new MinReplicationFactor();
4850
}
4951

5052
public Boolean getDoCompact() {
@@ -118,6 +120,14 @@ public void setReplicationFactor(final Integer replicationFactor) {
118120
this.replicationFactor.setReplicationFactor(replicationFactor);
119121
}
120122

123+
public Integer getMinReplicationFactor() {
124+
return minReplicationFactor.getMinReplicationFactor();
125+
}
126+
127+
public void setMinReplicationFactor(final Integer minReplicationFactor) {
128+
this.minReplicationFactor.setMinReplicationFactor(minReplicationFactor);
129+
}
130+
121131
/**
122132
* @return whether the collection is a satellite collection. Only in an enterprise cluster setup (else returning null).
123133
*/

src/main/java/com/arangodb/entity/GraphEntity.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public class GraphEntity implements Entity {
3939
private Boolean isSmart;
4040
private Integer numberOfShards;
4141
private String smartGraphAttribute;
42+
private Integer replicationFactor;
43+
private Integer minReplicationFactor;
4244

4345
public String getName() {
4446
return name != null ? name : _key;
@@ -60,6 +62,13 @@ public Integer getNumberOfShards() {
6062
return numberOfShards;
6163
}
6264

65+
public Integer getReplicationFactor() {
66+
return replicationFactor;
67+
}
68+
public Integer getMinReplicationFactor() {
69+
return minReplicationFactor;
70+
}
71+
6372
public String getSmartGraphAttribute() {
6473
return smartGraphAttribute;
6574
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* DISCLAIMER
3+
*
4+
* Copyright 2019 ArangoDB GmbH, Cologne, Germany
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
* Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
*/
20+
21+
package com.arangodb.entity;
22+
23+
/**
24+
* @author Heiko Kernbach
25+
*
26+
*/
27+
public class MinReplicationFactor {
28+
29+
private Integer minReplicationFactor;
30+
31+
public MinReplicationFactor() {
32+
super();
33+
}
34+
35+
public Integer getMinReplicationFactor() {
36+
return minReplicationFactor;
37+
}
38+
39+
public void setMinReplicationFactor(final Integer minReplicationFactor) {
40+
this.minReplicationFactor = minReplicationFactor;
41+
}
42+
43+
}

src/main/java/com/arangodb/internal/velocypack/VPackDeserializers.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,10 @@
2727
import java.util.Map;
2828
import java.util.Map.Entry;
2929

30+
import com.arangodb.entity.*;
3031
import org.slf4j.Logger;
3132
import org.slf4j.LoggerFactory;
3233

33-
import com.arangodb.entity.ArangoDBVersion;
34-
import com.arangodb.entity.BaseDocument;
35-
import com.arangodb.entity.BaseEdgeDocument;
36-
import com.arangodb.entity.CollectionStatus;
37-
import com.arangodb.entity.CollectionType;
38-
import com.arangodb.entity.License;
39-
import com.arangodb.entity.LogLevel;
40-
import com.arangodb.entity.Permissions;
41-
import com.arangodb.entity.QueryExecutionState;
42-
import com.arangodb.entity.ReplicationFactor;
43-
import com.arangodb.entity.ViewEntity;
44-
import com.arangodb.entity.ViewType;
4534
import com.arangodb.entity.arangosearch.ArangoSearchProperties;
4635
import com.arangodb.entity.arangosearch.ArangoSearchPropertiesEntity;
4736
import com.arangodb.entity.arangosearch.CollectionLink;
@@ -200,6 +189,18 @@ public ReplicationFactor deserialize(
200189
}
201190
};
202191

192+
public static final VPackDeserializer<MinReplicationFactor> MIN_REPLICATION_FACTOR = new VPackDeserializer<MinReplicationFactor>() {
193+
@Override
194+
public MinReplicationFactor deserialize(
195+
final VPackSlice parent,
196+
final VPackSlice vpack,
197+
final VPackDeserializationContext context) throws VPackException {
198+
final MinReplicationFactor minReplicationFactor = new MinReplicationFactor();
199+
minReplicationFactor.setMinReplicationFactor(vpack.getAsInt());
200+
return minReplicationFactor;
201+
}
202+
};
203+
203204
public static final VPackDeserializer<ViewType> VIEW_TYPE = new VPackDeserializer<ViewType>() {
204205
@Override
205206
public ViewType deserialize(

src/main/java/com/arangodb/internal/velocypack/VPackDriverModule.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.arangodb.entity.QueryEntity;
3535
import com.arangodb.entity.QueryExecutionState;
3636
import com.arangodb.entity.ReplicationFactor;
37+
import com.arangodb.entity.MinReplicationFactor;
3738
import com.arangodb.entity.ViewType;
3839
import com.arangodb.entity.arangosearch.ArangoSearchProperties;
3940
import com.arangodb.entity.arangosearch.ArangoSearchPropertiesEntity;
@@ -77,6 +78,7 @@ public String translateName(final Field field) {
7778
context.registerSerializer(LogLevel.class, VPackSerializers.LOG_LEVEL);
7879
context.registerSerializer(Permissions.class, VPackSerializers.PERMISSIONS);
7980
context.registerSerializer(ReplicationFactor.class, VPackSerializers.REPLICATION_FACTOR);
81+
context.registerSerializer(MinReplicationFactor.class, VPackSerializers.MIN_REPLICATION_FACTOR);
8082
context.registerSerializer(ViewType.class, VPackSerializers.VIEW_TYPE);
8183
context.registerSerializer(ArangoSearchPropertiesOptions.class, VPackSerializers.ARANGO_SEARCH_PROPERTIES_OPTIONS);
8284
context.registerSerializer(ArangoSearchProperties.class, VPackSerializers.ARANGO_SEARCH_PROPERTIES);

src/main/java/com/arangodb/internal/velocypack/VPackSerializers.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,7 @@
2525
import java.util.Map;
2626
import java.util.Map.Entry;
2727

28-
import com.arangodb.entity.BaseDocument;
29-
import com.arangodb.entity.BaseEdgeDocument;
30-
import com.arangodb.entity.CollectionType;
31-
import com.arangodb.entity.DocumentField;
32-
import com.arangodb.entity.LogLevel;
33-
import com.arangodb.entity.Permissions;
34-
import com.arangodb.entity.ReplicationFactor;
35-
import com.arangodb.entity.ViewType;
28+
import com.arangodb.entity.*;
3629
import com.arangodb.entity.arangosearch.ArangoSearchProperties;
3730
import com.arangodb.entity.arangosearch.CollectionLink;
3831
import com.arangodb.entity.arangosearch.ConsolidationType;
@@ -197,6 +190,17 @@ public void serialize(
197190
}
198191
};
199192

193+
public static final VPackSerializer<MinReplicationFactor> MIN_REPLICATION_FACTOR = new VPackSerializer<MinReplicationFactor>() {
194+
@Override
195+
public void serialize(
196+
final VPackBuilder builder,
197+
final String attribute,
198+
final MinReplicationFactor value,
199+
final VPackSerializationContext context) throws VPackException {
200+
builder.add(attribute, value.getMinReplicationFactor());
201+
}
202+
};
203+
200204
public static final VPackSerializer<ViewType> VIEW_TYPE = new VPackSerializer<ViewType>() {
201205
@Override
202206
public void serialize(

src/main/java/com/arangodb/model/CollectionCreateOptions.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.arangodb.entity.KeyOptions;
2525
import com.arangodb.entity.KeyType;
2626
import com.arangodb.entity.ReplicationFactor;
27+
import com.arangodb.entity.MinReplicationFactor;
2728

2829
/**
2930
* @author Mark Vollmary
@@ -36,6 +37,7 @@ public class CollectionCreateOptions {
3637
private String name;
3738
private Long journalSize;
3839
private final ReplicationFactor replicationFactor;
40+
private final MinReplicationFactor minReplicationFactor;
3941
private KeyOptions keyOptions;
4042
private Boolean waitForSync;
4143
private Boolean doCompact;
@@ -53,6 +55,7 @@ public class CollectionCreateOptions {
5355
public CollectionCreateOptions() {
5456
super();
5557
replicationFactor = new ReplicationFactor();
58+
minReplicationFactor = new MinReplicationFactor();
5659
}
5760

5861
protected String getName() {
@@ -87,6 +90,10 @@ public Integer getReplicationFactor() {
8790
return replicationFactor.getReplicationFactor();
8891
}
8992

93+
public Integer getMinReplicationFactor() {
94+
return minReplicationFactor.getMinReplicationFactor();
95+
}
96+
9097
/**
9198
* @param replicationFactor
9299
* (The default is 1): in a cluster, this attribute determines how many copies of each shard are kept on
@@ -103,6 +110,24 @@ public CollectionCreateOptions replicationFactor(final Integer replicationFactor
103110
return this;
104111
}
105112

113+
/**
114+
* @param minReplicationFactor
115+
* (optional, default is 1): in a cluster, this attribute determines how many desired copies of each
116+
* shard are kept on different DBServers. The value 1 means that only one copy (no synchronous
117+
* replication) is kept. A value of k means that desired k-1 replicas are kept. If in a failover scenario
118+
* a shard of a collection has less than minReplicationFactor many insync followers it will go into
119+
* "read-only" mode and will reject writes until enough followers are insync again. In more detail:
120+
* Having `minReplicationFactor == 1` means as soon as a "master-copy" is available of the data writes
121+
* are allowed. Having `minReplicationFactor > 1` requires additional insync copies on follower servers
122+
* to allow writes.
123+
*
124+
* @return options
125+
*/
126+
public CollectionCreateOptions minReplicationFactor(final Integer minReplicationFactor) {
127+
this.minReplicationFactor.setMinReplicationFactor(minReplicationFactor);
128+
return this;
129+
}
130+
106131
public Boolean getSatellite() {
107132
return replicationFactor.getSatellite();
108133
}

src/main/java/com/arangodb/model/GraphCreateOptions.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,28 @@ public GraphCreateOptions replicationFactor(final Integer replicationFactor) {
119119
return this;
120120
}
121121

122+
public Integer getMinReplicationFactor() {
123+
return getOptions().getMinReplicationFactor();
124+
}
125+
126+
/**
127+
* @param minReplicationFactor
128+
* (optional, default is 1): in a cluster, this attribute determines how many desired copies of each
129+
* shard are kept on different DBServers. The value 1 means that only one copy (no synchronous
130+
* replication) is kept. A value of k means that desired k-1 replicas are kept. If in a failover scenario
131+
* a shard of a collection has less than minReplicationFactor many insync followers it will go into
132+
* "read-only" mode and will reject writes until enough followers are insync again. In more detail:
133+
* Having `minReplicationFactor == 1` means as soon as a "master-copy" is available of the data writes
134+
* are allowed. Having `minReplicationFactor > 1` requires additional insync copies on follower servers
135+
* to allow writes.
136+
*
137+
* @return options
138+
*/
139+
public GraphCreateOptions minReplicationFactor(final Integer minReplicationFactor) {
140+
getOptions().setMinReplicationFactor(minReplicationFactor);
141+
return this;
142+
}
143+
122144
public Integer getNumberOfShards() {
123145
return getOptions().getNumberOfShards();
124146
}
@@ -157,6 +179,7 @@ private SmartOptions getOptions() {
157179

158180
public static class SmartOptions {
159181
private Integer replicationFactor;
182+
private Integer minReplicationFactor;
160183
private Integer numberOfShards;
161184
private String smartGraphAttribute;
162185

@@ -172,6 +195,14 @@ public void setReplicationFactor(final Integer replicationFactor) {
172195
this.replicationFactor = replicationFactor;
173196
}
174197

198+
public Integer getMinReplicationFactor() {
199+
return minReplicationFactor;
200+
}
201+
202+
public void setMinReplicationFactor(final Integer minReplicationFactor) {
203+
this.minReplicationFactor = minReplicationFactor;
204+
}
205+
175206
public Integer getNumberOfShards() {
176207
return numberOfShards;
177208
}

src/test/java/com/arangodb/ArangoDatabaseTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,37 @@ public void createCollectionWithReplicationFactor() {
212212

213213
}
214214

215+
@Test
216+
public void createCollectionWithMinReplicationFactor() {
217+
218+
// if we do not have version at least 3.5+ => exit
219+
if (!requireVersion(3, 5)) {
220+
LOG.info("Skip Test 'createCollectionWithMinReplicationFactor' because feature not implemented yet.");
221+
return;
222+
}
223+
224+
// if we do not have a cluster => exit
225+
if (arangoDB.getRole() == ServerRole.SINGLE) {
226+
return;
227+
}
228+
229+
try {
230+
final CollectionEntity result = db.createCollection(COLLECTION_NAME,
231+
new CollectionCreateOptions().replicationFactor(2).minReplicationFactor(2));
232+
assertThat(result, is(notNullValue()));
233+
assertThat(result.getId(), is(notNullValue()));
234+
assertThat(db.collection(COLLECTION_NAME).getProperties().getReplicationFactor(), is(2));
235+
assertThat(db.collection(COLLECTION_NAME).getProperties().getMinReplicationFactor(), is(2));
236+
assertThat(db.collection(COLLECTION_NAME).getProperties().getSatellite(), is(nullValue()));
237+
} catch (final ArangoDBException e) {
238+
e.printStackTrace();
239+
} finally {
240+
db.collection(COLLECTION_NAME).drop();
241+
}
242+
243+
}
244+
245+
215246
@Test
216247
public void createSatelliteCollection() {
217248
if (arangoDB.getVersion().getLicense() == License.COMMUNITY) {

0 commit comments

Comments
 (0)