Skip to content

Feature/min replication factor #282

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a

## [Unreleased]

### Added

- added minReplicationAttribute for collections and graphs

## [5.0.7] - 2019-07-19

### Fixed
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/arangodb/entity/CollectionPropertiesEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ public class CollectionPropertiesEntity extends CollectionEntity {
private Integer numberOfShards;
private Collection<String> shardKeys;
private final ReplicationFactor replicationFactor;
private final MinReplicationFactor minReplicationFactor;

private String shardingStrategy; // cluster option
private String smartJoinAttribute; // enterprise option

public CollectionPropertiesEntity() {
super();
replicationFactor = new ReplicationFactor();
minReplicationFactor = new MinReplicationFactor();
}

public Boolean getDoCompact() {
Expand Down Expand Up @@ -118,6 +120,14 @@ public void setReplicationFactor(final Integer replicationFactor) {
this.replicationFactor.setReplicationFactor(replicationFactor);
}

public Integer getMinReplicationFactor() {
return minReplicationFactor.getMinReplicationFactor();
}

public void setMinReplicationFactor(final Integer minReplicationFactor) {
this.minReplicationFactor.setMinReplicationFactor(minReplicationFactor);
}

/**
* @return whether the collection is a satellite collection. Only in an enterprise cluster setup (else returning null).
*/
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/com/arangodb/entity/GraphEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public class GraphEntity implements Entity {
private Boolean isSmart;
private Integer numberOfShards;
private String smartGraphAttribute;
private Integer replicationFactor;
private Integer minReplicationFactor;

public String getName() {
return name != null ? name : _key;
Expand All @@ -60,6 +62,13 @@ public Integer getNumberOfShards() {
return numberOfShards;
}

public Integer getReplicationFactor() {
return replicationFactor;
}
public Integer getMinReplicationFactor() {
return minReplicationFactor;
}

public String getSmartGraphAttribute() {
return smartGraphAttribute;
}
Expand Down
43 changes: 43 additions & 0 deletions src/main/java/com/arangodb/entity/MinReplicationFactor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* DISCLAIMER
*
* Copyright 2019 ArangoDB GmbH, Cologne, Germany
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright holder is ArangoDB GmbH, Cologne, Germany
*/

package com.arangodb.entity;

/**
* @author Heiko Kernbach
*
*/
public class MinReplicationFactor {

private Integer minReplicationFactor;

public MinReplicationFactor() {
super();
}

public Integer getMinReplicationFactor() {
return minReplicationFactor;
}

public void setMinReplicationFactor(final Integer minReplicationFactor) {
this.minReplicationFactor = minReplicationFactor;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,10 @@
import java.util.Map;
import java.util.Map.Entry;

import com.arangodb.entity.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.arangodb.entity.ArangoDBVersion;
import com.arangodb.entity.BaseDocument;
import com.arangodb.entity.BaseEdgeDocument;
import com.arangodb.entity.CollectionStatus;
import com.arangodb.entity.CollectionType;
import com.arangodb.entity.License;
import com.arangodb.entity.LogLevel;
import com.arangodb.entity.Permissions;
import com.arangodb.entity.QueryExecutionState;
import com.arangodb.entity.ReplicationFactor;
import com.arangodb.entity.ViewEntity;
import com.arangodb.entity.ViewType;
import com.arangodb.entity.arangosearch.ArangoSearchProperties;
import com.arangodb.entity.arangosearch.ArangoSearchPropertiesEntity;
import com.arangodb.entity.arangosearch.CollectionLink;
Expand Down Expand Up @@ -200,6 +189,18 @@ public ReplicationFactor deserialize(
}
};

public static final VPackDeserializer<MinReplicationFactor> MIN_REPLICATION_FACTOR = new VPackDeserializer<MinReplicationFactor>() {
@Override
public MinReplicationFactor deserialize(
final VPackSlice parent,
final VPackSlice vpack,
final VPackDeserializationContext context) throws VPackException {
final MinReplicationFactor minReplicationFactor = new MinReplicationFactor();
minReplicationFactor.setMinReplicationFactor(vpack.getAsInt());
return minReplicationFactor;
}
};

public static final VPackDeserializer<ViewType> VIEW_TYPE = new VPackDeserializer<ViewType>() {
@Override
public ViewType deserialize(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.arangodb.entity.QueryEntity;
import com.arangodb.entity.QueryExecutionState;
import com.arangodb.entity.ReplicationFactor;
import com.arangodb.entity.MinReplicationFactor;
import com.arangodb.entity.ViewType;
import com.arangodb.entity.arangosearch.ArangoSearchProperties;
import com.arangodb.entity.arangosearch.ArangoSearchPropertiesEntity;
Expand Down Expand Up @@ -77,6 +78,7 @@ public String translateName(final Field field) {
context.registerSerializer(LogLevel.class, VPackSerializers.LOG_LEVEL);
context.registerSerializer(Permissions.class, VPackSerializers.PERMISSIONS);
context.registerSerializer(ReplicationFactor.class, VPackSerializers.REPLICATION_FACTOR);
context.registerSerializer(MinReplicationFactor.class, VPackSerializers.MIN_REPLICATION_FACTOR);
context.registerSerializer(ViewType.class, VPackSerializers.VIEW_TYPE);
context.registerSerializer(ArangoSearchPropertiesOptions.class, VPackSerializers.ARANGO_SEARCH_PROPERTIES_OPTIONS);
context.registerSerializer(ArangoSearchProperties.class, VPackSerializers.ARANGO_SEARCH_PROPERTIES);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,7 @@
import java.util.Map;
import java.util.Map.Entry;

import com.arangodb.entity.BaseDocument;
import com.arangodb.entity.BaseEdgeDocument;
import com.arangodb.entity.CollectionType;
import com.arangodb.entity.DocumentField;
import com.arangodb.entity.LogLevel;
import com.arangodb.entity.Permissions;
import com.arangodb.entity.ReplicationFactor;
import com.arangodb.entity.ViewType;
import com.arangodb.entity.*;
import com.arangodb.entity.arangosearch.ArangoSearchProperties;
import com.arangodb.entity.arangosearch.CollectionLink;
import com.arangodb.entity.arangosearch.ConsolidationType;
Expand Down Expand Up @@ -197,6 +190,17 @@ public void serialize(
}
};

public static final VPackSerializer<MinReplicationFactor> MIN_REPLICATION_FACTOR = new VPackSerializer<MinReplicationFactor>() {
@Override
public void serialize(
final VPackBuilder builder,
final String attribute,
final MinReplicationFactor value,
final VPackSerializationContext context) throws VPackException {
builder.add(attribute, value.getMinReplicationFactor());
}
};

public static final VPackSerializer<ViewType> VIEW_TYPE = new VPackSerializer<ViewType>() {
@Override
public void serialize(
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/com/arangodb/model/CollectionCreateOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.arangodb.entity.KeyOptions;
import com.arangodb.entity.KeyType;
import com.arangodb.entity.ReplicationFactor;
import com.arangodb.entity.MinReplicationFactor;

/**
* @author Mark Vollmary
Expand All @@ -36,6 +37,7 @@ public class CollectionCreateOptions {
private String name;
private Long journalSize;
private final ReplicationFactor replicationFactor;
private final MinReplicationFactor minReplicationFactor;
private KeyOptions keyOptions;
private Boolean waitForSync;
private Boolean doCompact;
Expand All @@ -53,6 +55,7 @@ public class CollectionCreateOptions {
public CollectionCreateOptions() {
super();
replicationFactor = new ReplicationFactor();
minReplicationFactor = new MinReplicationFactor();
}

protected String getName() {
Expand Down Expand Up @@ -87,6 +90,10 @@ public Integer getReplicationFactor() {
return replicationFactor.getReplicationFactor();
}

public Integer getMinReplicationFactor() {
return minReplicationFactor.getMinReplicationFactor();
}

/**
* @param replicationFactor
* (The default is 1): in a cluster, this attribute determines how many copies of each shard are kept on
Expand All @@ -103,6 +110,24 @@ public CollectionCreateOptions replicationFactor(final Integer replicationFactor
return this;
}

/**
* @param minReplicationFactor
* (optional, default is 1): in a cluster, this attribute determines how many desired copies of each
* shard are kept on different DBServers. The value 1 means that only one copy (no synchronous
* replication) is kept. A value of k means that desired k-1 replicas are kept. If in a failover scenario
* a shard of a collection has less than minReplicationFactor many insync followers it will go into
* "read-only" mode and will reject writes until enough followers are insync again. In more detail:
* Having `minReplicationFactor == 1` means as soon as a "master-copy" is available of the data writes
* are allowed. Having `minReplicationFactor > 1` requires additional insync copies on follower servers
* to allow writes.
*
* @return options
*/
public CollectionCreateOptions minReplicationFactor(final Integer minReplicationFactor) {
this.minReplicationFactor.setMinReplicationFactor(minReplicationFactor);
return this;
}

public Boolean getSatellite() {
return replicationFactor.getSatellite();
}
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/com/arangodb/model/GraphCreateOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,28 @@ public GraphCreateOptions replicationFactor(final Integer replicationFactor) {
return this;
}

public Integer getMinReplicationFactor() {
return getOptions().getMinReplicationFactor();
}

/**
* @param minReplicationFactor
* (optional, default is 1): in a cluster, this attribute determines how many desired copies of each
* shard are kept on different DBServers. The value 1 means that only one copy (no synchronous
* replication) is kept. A value of k means that desired k-1 replicas are kept. If in a failover scenario
* a shard of a collection has less than minReplicationFactor many insync followers it will go into
* "read-only" mode and will reject writes until enough followers are insync again. In more detail:
* Having `minReplicationFactor == 1` means as soon as a "master-copy" is available of the data writes
* are allowed. Having `minReplicationFactor > 1` requires additional insync copies on follower servers
* to allow writes.
*
* @return options
*/
public GraphCreateOptions minReplicationFactor(final Integer minReplicationFactor) {
getOptions().setMinReplicationFactor(minReplicationFactor);
return this;
}

public Integer getNumberOfShards() {
return getOptions().getNumberOfShards();
}
Expand Down Expand Up @@ -157,6 +179,7 @@ private SmartOptions getOptions() {

public static class SmartOptions {
private Integer replicationFactor;
private Integer minReplicationFactor;
private Integer numberOfShards;
private String smartGraphAttribute;

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

public Integer getMinReplicationFactor() {
return minReplicationFactor;
}

public void setMinReplicationFactor(final Integer minReplicationFactor) {
this.minReplicationFactor = minReplicationFactor;
}

public Integer getNumberOfShards() {
return numberOfShards;
}
Expand Down
31 changes: 31 additions & 0 deletions src/test/java/com/arangodb/ArangoDatabaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,37 @@ public void createCollectionWithReplicationFactor() {

}

@Test
public void createCollectionWithMinReplicationFactor() {

// if we do not have version at least 3.5+ => exit
if (!requireVersion(3, 5)) {
LOG.info("Skip Test 'createCollectionWithMinReplicationFactor' because feature not implemented yet.");
return;
}

// if we do not have a cluster => exit
if (arangoDB.getRole() == ServerRole.SINGLE) {
return;
}

try {
final CollectionEntity result = db.createCollection(COLLECTION_NAME,
new CollectionCreateOptions().replicationFactor(2).minReplicationFactor(2));
assertThat(result, is(notNullValue()));
assertThat(result.getId(), is(notNullValue()));
assertThat(db.collection(COLLECTION_NAME).getProperties().getReplicationFactor(), is(2));
assertThat(db.collection(COLLECTION_NAME).getProperties().getMinReplicationFactor(), is(2));
assertThat(db.collection(COLLECTION_NAME).getProperties().getSatellite(), is(nullValue()));
} catch (final ArangoDBException e) {
e.printStackTrace();
} finally {
db.collection(COLLECTION_NAME).drop();
}

}


@Test
public void createSatelliteCollection() {
if (arangoDB.getVersion().getLicense() == License.COMMUNITY) {
Expand Down
Loading