org.eclipse.ditto.internal.utils.namespaces.BlockedNamespaces Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ditto-internal-utils-namespaces Show documentation
Show all versions of ditto-internal-utils-namespaces Show documentation
Eclipse Ditto is a framework for creating and managing digital twins in the IoT.
/*
* Copyright (c) 2017 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.ditto.internal.utils.namespaces;
import java.util.concurrent.CompletionStage;
import org.eclipse.ditto.internal.utils.ddata.DistributedData;
import org.eclipse.ditto.internal.utils.ddata.DistributedDataConfig;
import org.apache.pekko.actor.ActorSystem;
import org.apache.pekko.actor.ExtendedActorSystem;
import org.apache.pekko.cluster.Cluster;
import org.apache.pekko.cluster.ddata.Key;
import org.apache.pekko.cluster.ddata.ORSet;
import org.apache.pekko.cluster.ddata.ORSetKey;
import org.apache.pekko.cluster.ddata.Replicator;
import org.apache.pekko.cluster.ddata.SelfUniqueAddress;
/**
* Distributed data for blocking of messages addressed entities in certain namespaces.
*/
public final class BlockedNamespaces extends DistributedData> {
/**
* Role of cluster members to which this distributed data is replicated.
*/
public static final String CLUSTER_ROLE = "blocked-namespaces-aware";
/**
* Name of the replicator actor.
*/
public static final String ACTOR_NAME = "blockedNamespacesReplicator";
/**
* Key of the distributed data. Should be unique among ORSets.
*/
private static final Key> KEY = ORSetKey.create("BlockedNamespaces");
private static final String BLOCKED_NAMESPACES_DISPATCHER = "blocked-namespaces-dispatcher";
private final SelfUniqueAddress selfUniqueAddress;
private BlockedNamespaces(final DistributedDataConfig config, final ActorSystem system) {
super(config, system, system.dispatchers().lookup(BLOCKED_NAMESPACES_DISPATCHER));
selfUniqueAddress = SelfUniqueAddress.apply(Cluster.get(system).selfUniqueAddress());
}
/**
* Get an instance of this distributed data with the default configuration. The provided Pekko system must be a
* cluster member with the role {@code blocked-namespaces-aware}.
*
* @param system the actor system where the replicator actor will be created.
* @return a new instance of the distributed data.
*/
public static BlockedNamespaces of(final ActorSystem system) {
return Provider.INSTANCE.get(system);
}
/**
* Create an instance of this distributed data with special configuration.
*
* @param config the overriding configuration.
* @param system the actor system where the replicator actor will be created.
* @return a new instance of the distributed data.
* @throws NullPointerException if {@code configReader} is {@code null}.
*/
public static BlockedNamespaces create(final DistributedDataConfig config, final ActorSystem system) {
return new BlockedNamespaces(config, system);
}
/**
* Test whether a namespace is stored in the local replica with the configured READ timeout.
*
* @param namespace the namespace.
* @return whether the local replica is retrieved successfully and contains the namespace.
*/
public CompletionStage contains(final String namespace) {
// for blocked namespaces, only 1 shard is used:
return get(getKey(0), (Replicator.ReadConsistency) Replicator.readLocal())
.thenApply(maybeORSet -> maybeORSet.orElse(ORSet.empty()).contains(namespace))
.exceptionally(error -> false);
}
/**
* Write a namespace to ALL replicas with the configured WRITE timeout.
*
* @param namespace the namespace.
* @return future that completes after the update propagates to all replicas, exceptionally if there is any error.
*/
public CompletionStage add(final String namespace) {
// for blocked namespaces, only 1 shard is used:
return update(getKey(0), writeAll(), orSet -> orSet.add(selfUniqueAddress, namespace));
}
/**
* Remove a namespace from ALL replicas with the configured WRITE timeout.
*
* @param namespace the namespace to remove.
* @return future that completes after the removal propagates to all replicas, exceptionally if there is any error.
*/
public CompletionStage remove(final String namespace) {
// for blocked namespaces, only 1 shard is used:
return update(getKey(0), writeAll(), orSet -> orSet.remove(selfUniqueAddress, namespace));
}
@Override
protected Key> getKey(final int shardNumber) {
// for blocked namespaces, only 1 shard is used, so use a static key:
return KEY;
}
@Override
protected ORSet getInitialValue() {
return ORSet.empty();
}
private Replicator.WriteConsistency writeAll() {
return new Replicator.WriteAll(writeTimeout);
}
private static final class Provider
extends DistributedData.AbstractDDataProvider, BlockedNamespaces> {
private static final Provider INSTANCE = new Provider();
private Provider() {}
@Override
public BlockedNamespaces createExtension(final ExtendedActorSystem system) {
return new BlockedNamespaces(DistributedData.createConfig(system, ACTOR_NAME, CLUSTER_ROLE), system);
}
}
}