/*
* Copyright 2014 Alexey Plotnik
*
* 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 org.stem.domain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stem.coordination.Event;
import org.stem.coordination.EventFuture;
import org.stem.coordination.EventManager;
import org.stem.coordination.ZNodeAbstract;
import org.stem.domain.topology.Topology;
import org.stem.exceptions.StemException;
import org.stem.policies.AutoPlacementPolicy;
import org.stem.policies.Node2RackAssigner;
import java.util.*;
public class Unauthorized {
private static final Logger logger = LoggerFactory.getLogger(Unauthorized.class);
private final Cluster cluster;
final Map<UUID, NodeInsertMeta> registry = new HashMap<>();
private final AutoPlacementPolicy placementPolicy;
public Unauthorized(Cluster cluster) {
this.cluster = cluster;
this.placementPolicy = new Node2RackAssigner("DC1");
this.placementPolicy.init(cluster);
}
public AutoPlacementPolicy getPlacementPolicy() {
return placementPolicy;
}
public void add(Topology.StorageNode node, EventFuture future) {
// TODO: validation StorageNode object
synchronized (cluster) {
if (null != registry.get(node.id))
throw new StemException(String.format("Node with id=%s is already in pending list", node.id));
Topology.StorageNode existing = cluster.topology2.findStorageNode(node.id);
if (null != existing)
throw new StemException(String.format("Node with id=%s already exist in cluster", node.id));
NodeInsertMeta meta = new NodeInsertMeta(node, future);
registry.put(node.id, meta);
}
}
//TODO: clear registry or delete specific node
public List<Topology.StorageNode> list() {
List<Topology.StorageNode> result = new ArrayList<>();
for (NodeInsertMeta meta : registry.values()) {
result.add(meta.node);
}
return result;
}
public Topology.StorageNode get(UUID id) {
return getMeta(id).node;
}
private NodeInsertMeta getMeta(UUID id) {
NodeInsertMeta meta = registry.get(id);
if (null == meta)
throw new StemException(String.format("Node with id=%s can not be found", id));
else
return meta;
}
public Event.Join approveNew(UUID id, String datacenter, String rack) {
synchronized (cluster) {
NodeInsertMeta meta = getMeta(id);
EventFuture future = meta.future();
Event.Join result;
//try {
cluster.addStorageNode(meta.node, datacenter, rack);
registry.remove(id);
result = success("Node was successfully added to cluster");
future.setResult(result);
return result;
// } catch (TopologyException e) {
// result = failed("Node can not be added to cluster: " + e.getMessage());
// future.setResult(result);
// logger.error("Failed to add node to cluster", e);
// return result;
//
// } catch (Exception e) {
// result = failed("Node can not be added to cluster: Unexpected error");
// future.setResult(result);
// logger.error("Failed to add node to cluster", e);
// return result;
// }
}
}
public Event.Join approveExisting(UUID uuid) {
try {
synchronized (cluster) {
EventFuture future = EventManager.instance.readSubscription(uuid);
Event.Join result = success("Existing node has successfully joined back to cluster");
future.setResult(result);
return result;
}
} catch (Exception e) {
return failed("Node can not be added to cluster: Unexpected error");
// TODO
}
}
public Event.Join deny(UUID id) {
synchronized (cluster) {
NodeInsertMeta meta = getMeta(id);
EventFuture future = meta.future();
Event.Join result;
registry.remove(id);
result = failed("User refuses node with id=" + id);
future.setResult(result);
return result;
}
}
private static Event.Join success(String message) {
return new Event.Join(Event.Join.Result.SUCCESS, message);
}
private static Event.Join failed(String message) {
return new Event.Join(Event.Join.Result.ERROR, message);
}
/**
*
*/
private class NodeInsertMeta extends ZNodeAbstract {
private Topology.StorageNode node;
private UUID eventId;
private EventFuture future;
public NodeInsertMeta(Topology.StorageNode node, EventFuture future) {
this.node = node;
this.future = future;
this.eventId = future.eventId();
}
public NodeInsertMeta(Topology.StorageNode node, UUID eventId) throws Exception {
this.node = node;
this.future = EventManager.instance.readSubscription(eventId);
this.eventId = eventId;
}
public NodeInsertMeta() {
}
public EventFuture future() {
return future;
}
@Override
public String name() {
return node.getId().toString();
}
}
}