com.arangodb.ArangoDB Maven / Gradle / Ivy
/*
* DISCLAIMER
*
* Copyright 2016 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;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.net.ssl.SSLContext;
import com.arangodb.entity.ArangoDBVersion;
import com.arangodb.entity.LoadBalancingStrategy;
import com.arangodb.entity.LogEntity;
import com.arangodb.entity.LogLevelEntity;
import com.arangodb.entity.Permissions;
import com.arangodb.entity.ServerRole;
import com.arangodb.entity.UserEntity;
import com.arangodb.internal.ArangoDBConstants;
import com.arangodb.internal.ArangoExecutor.ResponseDeserializer;
import com.arangodb.internal.ArangoExecutorSync;
import com.arangodb.internal.CollectionCache;
import com.arangodb.internal.CollectionCache.DBAccess;
import com.arangodb.internal.DocumentCache;
import com.arangodb.internal.Host;
import com.arangodb.internal.InternalArangoDB;
import com.arangodb.internal.http.HttpCommunication;
import com.arangodb.internal.http.HttpProtocol;
import com.arangodb.internal.net.CommunicationProtocol;
import com.arangodb.internal.net.ExtendedHostResolver;
import com.arangodb.internal.net.FallbackHostHandler;
import com.arangodb.internal.net.HostHandle;
import com.arangodb.internal.net.HostHandler;
import com.arangodb.internal.net.HostResolver;
import com.arangodb.internal.net.HostResolver.EndpointResolver;
import com.arangodb.internal.net.RandomHostHandler;
import com.arangodb.internal.net.RoundRobinHostHandler;
import com.arangodb.internal.net.SimpleHostResolver;
import com.arangodb.internal.util.ArangoDeserializerImpl;
import com.arangodb.internal.util.ArangoSerializerImpl;
import com.arangodb.internal.util.ArangoUtilImpl;
import com.arangodb.internal.velocypack.VPackDocumentModule;
import com.arangodb.internal.velocypack.VPackDriverModule;
import com.arangodb.internal.velocystream.VstCommunicationSync;
import com.arangodb.internal.velocystream.VstProtocol;
import com.arangodb.internal.velocystream.internal.ConnectionSync;
import com.arangodb.model.LogOptions;
import com.arangodb.model.UserCreateOptions;
import com.arangodb.model.UserUpdateOptions;
import com.arangodb.util.ArangoCursorInitializer;
import com.arangodb.util.ArangoDeserializer;
import com.arangodb.util.ArangoSerialization;
import com.arangodb.util.ArangoSerializer;
import com.arangodb.velocypack.VPack;
import com.arangodb.velocypack.VPackAnnotationFieldFilter;
import com.arangodb.velocypack.VPackAnnotationFieldNaming;
import com.arangodb.velocypack.VPackDeserializer;
import com.arangodb.velocypack.VPackInstanceCreator;
import com.arangodb.velocypack.VPackJsonDeserializer;
import com.arangodb.velocypack.VPackJsonSerializer;
import com.arangodb.velocypack.VPackModule;
import com.arangodb.velocypack.VPackParser;
import com.arangodb.velocypack.VPackParserModule;
import com.arangodb.velocypack.VPackSerializer;
import com.arangodb.velocypack.VPackSlice;
import com.arangodb.velocypack.ValueType;
import com.arangodb.velocypack.exception.VPackException;
import com.arangodb.velocystream.Request;
import com.arangodb.velocystream.RequestType;
import com.arangodb.velocystream.Response;
/**
* @author Mark Vollmary
*
*/
public class ArangoDB extends InternalArangoDB {
public static class Builder {
private final List hosts;
private Host host;
private Integer timeout;
private String user;
private String password;
private Boolean useSsl;
private SSLContext sslContext;
private Integer chunksize;
private Integer maxConnections;
private final VPack.Builder vpackBuilder;
private final VPackParser.Builder vpackParserBuilder;
private ArangoSerializer serializer;
private ArangoDeserializer deserializer;
private Protocol protocol;
private Boolean acquireHostList;
private LoadBalancingStrategy loadBalancingStrategy;
public Builder() {
super();
vpackBuilder = new VPack.Builder();
vpackParserBuilder = new VPackParser.Builder();
vpackBuilder.registerModule(new VPackDriverModule());
vpackParserBuilder.registerModule(new VPackDriverModule());
host = new Host(ArangoDBConstants.DEFAULT_HOST, ArangoDBConstants.DEFAULT_PORT);
hosts = new ArrayList();
user = ArangoDBConstants.DEFAULT_USER;
loadProperties(ArangoDB.class.getResourceAsStream(DEFAULT_PROPERTY_FILE));
}
public Builder loadProperties(final InputStream in) throws ArangoDBException {
if (in != null) {
final Properties properties = new Properties();
try {
properties.load(in);
loadHosts(properties, this.hosts);
final String host = loadHost(properties, this.host.getHost());
final int port = loadPort(properties, this.host.getPort());
this.host = new Host(host, port);
timeout = loadTimeout(properties, timeout);
user = loadUser(properties, user);
password = loadPassword(properties, password);
useSsl = loadUseSsl(properties, useSsl);
chunksize = loadChunkSize(properties, chunksize);
maxConnections = loadMaxConnections(properties, maxConnections);
protocol = loadProtocol(properties, protocol);
acquireHostList = loadAcquireHostList(properties, acquireHostList);
loadBalancingStrategy = loadLoadBalancingStrategy(properties, loadBalancingStrategy);
} catch (final IOException e) {
throw new ArangoDBException(e);
}
}
return this;
}
/**
* @deprecated will be removed in version 4.2.0 use {@link #host(String, int)} instead
*
* @param host
* @return
*/
@Deprecated
public Builder host(final String host) {
this.host = new Host(host, this.host.getPort());
return this;
}
/**
* @deprecated will be removed in version 4.2.0 use {@link #host(String, int)} instead
*
* @param port
* @return
*/
@Deprecated
public Builder port(final Integer port) {
host = new Host(host.getHost(), port);
return this;
}
/**
* Adds a host to connect to. Multiple hosts can be added to provide fallbacks.
*
* @param host
* address of the host
* @param port
* port of the host
* @return {@link ArangoDB.Builder}
*/
public Builder host(final String host, final int port) {
hosts.add(new Host(host, port));
return this;
}
public Builder timeout(final Integer timeout) {
this.timeout = timeout;
return this;
}
public Builder user(final String user) {
this.user = user;
return this;
}
public Builder password(final String password) {
this.password = password;
return this;
}
public Builder useSsl(final Boolean useSsl) {
this.useSsl = useSsl;
return this;
}
public Builder sslContext(final SSLContext sslContext) {
this.sslContext = sslContext;
return this;
}
public Builder chunksize(final Integer chunksize) {
this.chunksize = chunksize;
return this;
}
public Builder maxConnections(final Integer maxConnections) {
this.maxConnections = maxConnections;
return this;
}
public Builder useProtocol(final Protocol protocol) {
this.protocol = protocol;
return this;
}
public Builder acquireHostList(final Boolean acquireHostList) {
this.acquireHostList = acquireHostList;
return this;
}
public Builder loadBalancingStrategy(final LoadBalancingStrategy loadBalancingStrategy) {
this.loadBalancingStrategy = loadBalancingStrategy;
return this;
}
public Builder registerSerializer(final Class clazz, final VPackSerializer serializer) {
vpackBuilder.registerSerializer(clazz, serializer);
return this;
}
/**
* Register a special serializer for a member class which can only be identified by its enclosing class.
*
* @param clazz
* type of the enclosing class
* @param serializer
* serializer to register
* @return builder
*/
public Builder registerEnclosingSerializer(final Class clazz, final VPackSerializer serializer) {
vpackBuilder.registerEnclosingSerializer(clazz, serializer);
return this;
}
public Builder registerDeserializer(final Class clazz, final VPackDeserializer deserializer) {
vpackBuilder.registerDeserializer(clazz, deserializer);
return this;
}
public Builder registerInstanceCreator(final Class clazz, final VPackInstanceCreator creator) {
vpackBuilder.registerInstanceCreator(clazz, creator);
return this;
}
public Builder registerJsonDeserializer(final ValueType type, final VPackJsonDeserializer deserializer) {
vpackParserBuilder.registerDeserializer(type, deserializer);
return this;
}
public Builder registerJsonDeserializer(
final String attribute,
final ValueType type,
final VPackJsonDeserializer deserializer) {
vpackParserBuilder.registerDeserializer(attribute, type, deserializer);
return this;
}
public Builder registerJsonSerializer(final Class clazz, final VPackJsonSerializer serializer) {
vpackParserBuilder.registerSerializer(clazz, serializer);
return this;
}
public Builder registerJsonSerializer(
final String attribute,
final Class clazz,
final VPackJsonSerializer serializer) {
vpackParserBuilder.registerSerializer(attribute, clazz, serializer);
return this;
}
public Builder annotationFieldFilter(
final Class type,
final VPackAnnotationFieldFilter fieldFilter) {
vpackBuilder.annotationFieldFilter(type, fieldFilter);
return this;
}
public Builder annotationFieldNaming(
final Class type,
final VPackAnnotationFieldNaming fieldNaming) {
vpackBuilder.annotationFieldNaming(type, fieldNaming);
return this;
}
public Builder registerModule(final VPackModule module) {
vpackBuilder.registerModule(module);
return this;
}
public Builder registerModules(final VPackModule... modules) {
vpackBuilder.registerModules(modules);
return this;
}
public Builder registerJsonModule(final VPackParserModule module) {
vpackParserBuilder.registerModule(module);
return this;
}
public Builder registerJsonModules(final VPackParserModule... module) {
vpackParserBuilder.registerModules(module);
return this;
}
/**
* Replace the built-in serializer with the given serializer.
*
*
* ATTENTION!: Use at your own risk
*
* @param serializer
* custom serializer
* @return builder
*/
public Builder setSerializer(final ArangoSerializer serializer) {
this.serializer = serializer;
return this;
}
/**
* Replace the built-in deserializer with the given deserializer.
*
*
* ATTENTION!: Use at your own risk
*
* @param deserializer
* custom deserializer
* @return builder
*/
public Builder setDeserializer(final ArangoDeserializer deserializer) {
this.deserializer = deserializer;
return this;
}
public synchronized ArangoDB build() {
if (hosts.isEmpty()) {
hosts.add(host);
}
final CollectionCache collectionCache = new CollectionCache();
vpackBuilder.registerModule(new VPackDocumentModule(collectionCache));
vpackParserBuilder.registerModule(new VPackDocumentModule(collectionCache));
final VPack vpacker = vpackBuilder.serializeNullValues(false).build();
final VPack vpackerNull = vpackBuilder.serializeNullValues(true).build();
final VPackParser vpackParser = vpackParserBuilder.build();
final ArangoSerializer serializerTemp = serializer != null ? serializer
: new ArangoSerializerImpl(vpacker, vpackerNull, vpackParser);
final ArangoDeserializer deserializerTemp = deserializer != null ? deserializer
: new ArangoDeserializerImpl(vpackerNull, vpackParser);
final HostResolver hostResolver = createHostResolver();
final HostHandler hostHandler = createHostHandler(hostResolver);
return new ArangoDB(
new VstCommunicationSync.Builder(hostHandler).timeout(timeout).user(user).password(password)
.useSsl(useSsl).sslContext(sslContext).chunksize(chunksize).maxConnections(maxConnections),
new HttpCommunication.Builder(hostHandler, protocol).timeout(timeout).user(user).password(password)
.useSsl(useSsl).sslContext(sslContext).maxConnections(maxConnections),
new ArangoUtilImpl(serializerTemp, deserializerTemp), collectionCache, protocol, hostResolver);
}
private HostResolver createHostResolver() {
return acquireHostList != null && acquireHostList.booleanValue()
? new ExtendedHostResolver(new ArrayList(hosts))
: new SimpleHostResolver(new ArrayList(hosts));
}
private HostHandler createHostHandler(final HostResolver hostResolver) {
final HostHandler hostHandler;
if (loadBalancingStrategy != null) {
switch (loadBalancingStrategy) {
case ONE_RANDOM:
hostHandler = new RandomHostHandler(hostResolver, new FallbackHostHandler(hostResolver));
break;
case ROUND_ROBIN:
hostHandler = new RoundRobinHostHandler(hostResolver);
break;
case NONE:
default:
hostHandler = new FallbackHostHandler(hostResolver);
break;
}
} else {
hostHandler = new FallbackHostHandler(hostResolver);
}
return hostHandler;
}
}
private ArangoCursorInitializer cursorInitializer;
private CommunicationProtocol cp;
public ArangoDB(final VstCommunicationSync.Builder vstBuilder, final HttpCommunication.Builder httpBuilder,
final ArangoSerialization util, final CollectionCache collectionCache, final Protocol protocol,
final HostResolver hostResolver) {
super(new ArangoExecutorSync(createProtocol(vstBuilder, httpBuilder, util, collectionCache, protocol), util,
new DocumentCache()), util);
cp = createProtocol(new VstCommunicationSync.Builder(vstBuilder).maxConnections(1),
new HttpCommunication.Builder(httpBuilder).maxConnections(1), util, collectionCache, protocol);
collectionCache.init(new DBAccess() {
@Override
public ArangoDatabase db(final String name) {
return new ArangoDatabase(cp, util, executor.documentCache(), name)
.setCursorInitializer(cursorInitializer);
}
});
hostResolver.init(new EndpointResolver() {
@Override
public Collection resolve(final boolean closeConnections) throws ArangoDBException {
Collection response;
try {
response = executor.execute(
new Request(ArangoDBConstants.SYSTEM, RequestType.GET, ArangoDBConstants.PATH_ENDPOINTS),
new ResponseDeserializer>() {
@Override
public Collection deserialize(final Response response) throws VPackException {
final VPackSlice field = response.getBody().get(ArangoDBConstants.ENDPOINTS);
Collection endpoints;
if (field.isNone()) {
endpoints = Collections. emptyList();
} else {
final Collection
© 2015 - 2025 Weber Informatics LLC | Privacy Policy