com.datastax.oss.simulacron.server.BoundCluster Maven / Gradle / Ivy
The newest version!
/*
* Copyright DataStax, Inc.
*
* 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.
*/
package com.datastax.oss.simulacron.server;
import static com.datastax.oss.simulacron.server.FrameCodecUtils.buildFrameCodec;
import static com.datastax.oss.simulacron.server.FrameCodecUtils.defaultFrameCodec;
import com.datastax.oss.protocol.internal.Frame;
import com.datastax.oss.simulacron.common.cluster.AbstractCluster;
import com.datastax.oss.simulacron.common.cluster.ClusterConnectionReport;
import com.datastax.oss.simulacron.common.cluster.ClusterQueryLogReport;
import com.datastax.oss.simulacron.common.cluster.ClusterSpec;
import com.datastax.oss.simulacron.common.cluster.NodeConnectionReport;
import com.datastax.oss.simulacron.common.cluster.QueryLog;
import com.datastax.oss.simulacron.common.stubbing.CloseType;
import com.datastax.oss.simulacron.common.stubbing.StubMapping;
import com.datastax.oss.simulacron.server.listener.QueryListener;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.netty.channel.Channel;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* A wrapper around {@link ClusterSpec} that is bound to a {@link Server}. If used as {@link
* java.io.Closeable} will unbind itself form its bound server.
*/
public class BoundCluster extends AbstractCluster
implements BoundTopic {
private final transient Server server;
private final transient StubStore stubStore;
private final transient List queryListeners = new ArrayList<>();
private final transient FrameCodecWrapper frameCodec;
BoundCluster(ClusterSpec delegate, Long clusterId, Server server) {
super(
delegate.getName(),
clusterId,
delegate.getCassandraVersion(),
delegate.getDSEVersion(),
delegate.getPeerInfo());
this.server = server;
this.stubStore = new StubStore();
this.frameCodec = buildFrameCodec(delegate).orElse(defaultFrameCodec());
}
@Override
public StubStore getStubStore() {
return stubStore;
}
@Override
public int clearPrimes(boolean nested) {
int cleared = getStubStore().clear();
if (nested) {
for (BoundDataCenter dc : getDataCenters()) {
cleared += dc.clearPrimes(true);
}
}
return cleared;
}
@Override
public CompletionStage unregisterAsync() {
return getServer().unregisterAsync(this);
}
@Override
public ClusterConnectionReport getConnections() {
ClusterConnectionReport clusterConnectionReport = new ClusterConnectionReport(getId());
for (BoundNode node : this.getNodes()) {
clusterConnectionReport.addNode(
node,
node.clientChannelGroup.stream().map(Channel::remoteAddress).collect(Collectors.toList()),
node.getAddress());
}
return clusterConnectionReport;
}
@Override
public CompletionStage closeConnectionsAsync(CloseType closeType) {
ClusterConnectionReport report = getConnections();
return CompletableFuture.allOf(
this.getNodes().stream()
.map(n -> n.closeConnectionsAsync(closeType).toCompletableFuture())
.collect(Collectors.toList())
.toArray(new CompletableFuture[] {}))
.thenApply(v -> report);
}
@Override
public CompletionStage closeConnectionAsync(
SocketAddress connection, CloseType type) {
for (BoundNode node : this.getNodes()) {
// identify the node that has the connection and close it with that node.
for (SocketAddress address : node.getConnections().getConnections()) {
if (connection.equals(address)) {
return node.closeConnectionAsync(address, type)
.thenApply(NodeConnectionReport::getRootReport);
}
}
}
CompletableFuture failedFuture = new CompletableFuture<>();
failedFuture.completeExceptionally(new IllegalArgumentException("Not found"));
return failedFuture;
}
@Override
public ClusterConnectionReport pauseRead() {
this.getNodes().forEach(BoundNode::pauseRead);
return getConnections();
}
@Override
public ClusterConnectionReport resumeRead() {
this.getNodes().forEach(BoundNode::resumeRead);
return getConnections();
}
/**
* Returns a QueryLogReport that contains all the logs for this cluster
*
* @return QueryLogReport
*/
@Override
@JsonIgnore
public ClusterQueryLogReport getLogs() {
ClusterQueryLogReport clusterQueryLogReport = new ClusterQueryLogReport(getId());
this.getNodes().forEach(n -> clusterQueryLogReport.addNode(n, n.activityLog.getLogs()));
return clusterQueryLogReport;
}
/**
* Returns a QueryLogReport that contains filtered logs for this cluster
*
* @return QueryLogReport
*/
@Override
@JsonIgnore
public ClusterQueryLogReport getLogs(boolean primed) {
ClusterQueryLogReport clusterQueryLogReport = new ClusterQueryLogReport(getId());
this.getNodes().forEach(n -> clusterQueryLogReport.addNode(n, n.activityLog.getLogs(primed)));
return clusterQueryLogReport;
}
@Override
public void registerQueryListener(
QueryListener queryListener, boolean after, Predicate filter) {
queryListeners.add(new QueryListenerWrapper(queryListener, after, filter));
}
@Override
public Server getServer() {
return server;
}
@Override
@JsonIgnore
public FrameCodecWrapper getFrameCodec() {
return frameCodec;
}
Optional find(BoundNode node, Frame frame) {
Optional stub = stubStore.find(node, frame);
if (!stub.isPresent() && server != null) {
stub = server.stubStore.find(node, frame);
}
return stub;
}
void notifyQueryListeners(BoundNode node, QueryLog queryLog, boolean after) {
if (queryLog != null && !queryListeners.isEmpty()) {
for (QueryListenerWrapper wrapper : queryListeners) {
if (after == wrapper.after) {
wrapper.apply(node, queryLog);
}
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy