diff --git a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/AbstractNodeWithManageable.java b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/AbstractNodeWithManageable.java deleted file mode 100644 index 269c83a1ca..0000000000 --- a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/AbstractNodeWithManageable.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright Terracotta, 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 org.terracotta.management.model.cluster; - -import org.terracotta.management.model.context.Context; - -import java.io.Serializable; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * @author Mathieu Carbou - */ -abstract class AbstractNodeWithManageable

extends AbstractNode

implements NodeWithManageable, Serializable { - - // services, server entities, client entities, etc. - private final ConcurrentMap manageables = new ConcurrentHashMap<>(); - - public AbstractNodeWithManageable(String id) { - super(id); - } - - @Override - public final Map getManageables() { - return manageables; - } - - @Override - public final int getManageableCount() { - return manageables.size(); - } - - @Override - public final Stream manageableStream() { - return manageables.values().stream(); - } - - @Override - @SuppressWarnings("unchecked") - public final B addManageable(Manageable manageable) { - // manageabled are unique per their ID but also per their combination of (type + name) - for (Manageable m : manageables.values()) { - if (m.is(manageable.getType(), manageable.getName())) { - throw new IllegalArgumentException("Duplicate manageable: type=" + manageable.getType() + ", name=" + manageable.getName()); - } - } - if (manageables.putIfAbsent(manageable.getId(), manageable) != null) { - throw new IllegalArgumentException("Duplicate manageable: " + manageable.getId()); - } - manageable.setParent(this); - return (B) this; - } - - @Override - public final Optional getManageable(Context context) { - return getManageable(context.get(Manageable.KEY)); - } - - @Override - public final Optional getManageable(String id) { - return id == null ? Optional.empty() : Optional.ofNullable(manageables.get(id)); - } - - @Override - public final Optional getManageable(String name, String type) { - return manageableStream().filter(manageable -> manageable.is(name, type)).findFirst(); - } - - @Override - public final boolean hasManageable(String name, String type) { - return getManageable(name, type).isPresent(); - } - - @Override - public final Optional removeManageable(String id) { - Optional manageable = getManageable(id); - manageable.ifPresent(m -> { - if (manageables.remove(id, m)) { - m.detach(); - } - }); - return manageable; - } - - @Override - public final Stream manageableStream(String type) { - return manageableStream().filter(manageable -> manageable.isType(type)); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - AbstractNodeWithManageable that = (AbstractNodeWithManageable) o; - return manageables.equals(that.manageables); - } - - @Override - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + manageables.hashCode(); - return result; - } - - @Override - public Map toMap() { - Map map = super.toMap(); - map.put("manageables", manageableStream().sorted((o1, o2) -> o1.getId().compareTo(o2.getId())).map(Manageable::toMap).collect(Collectors.toList())); - return map; - } - -} diff --git a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Client.java b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Client.java index 4e2aea05de..8611e123af 100644 --- a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Client.java +++ b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Client.java @@ -32,7 +32,7 @@ /** * @author Mathieu Carbou */ -public final class Client extends AbstractNodeWithManageable implements Serializable { +public final class Client extends AbstractNode implements Serializable { private static final long serialVersionUID = 1; @@ -44,12 +44,22 @@ public final class Client extends AbstractNodeWithManageable im private final ClientIdentifier clientIdentifier; private final SortedSet tags = new TreeSet<>(); private String hostName; + private ManagementRegistry managementRegistry; private Client(ClientIdentifier clientIdentifier) { super(clientIdentifier.getClientId()); this.clientIdentifier = Objects.requireNonNull(clientIdentifier); } + public Optional getManagementRegistry() { + return Optional.ofNullable(managementRegistry); + } + + public Client setManagementRegistry(ManagementRegistry managementRegistry) { + this.managementRegistry = managementRegistry; + return this; + } + public SortedSet getTags() { return tags; } @@ -161,16 +171,14 @@ public Optional removeConnection(String id) { return connection; } - public Stream serverManageableStream() { + public Stream fetchedServerEntityStream() { return connectionStream() - .filter(Connection::isConnectedToActiveServer) - .flatMap(Connection::serverManageableStream); + .flatMap(Connection::fetchedServerEntityStream); } - public int getServerManageableCount() { + public int getFetchedServerEntityCount() { return connectionStream() - .filter(Connection::isConnectedToActiveServer) - .mapToInt(Connection::getServerManageableCount).sum(); + .mapToInt(Connection::getFetchedServerEntityCount).sum(); } @Override @@ -189,16 +197,12 @@ public boolean isConnected() { return connectionStream().filter(Connection::isConnected).findFirst().isPresent(); } - public boolean isConnectedToActive() { - return connectionStream().filter(Connection::isConnectedToActiveServer).findFirst().isPresent(); - } - - public boolean isConnectedToServerManageable(String name, String type) { - return getServerManageable(name, type).isPresent(); + public boolean hasFetchedServerEntity(String name, String type) { + return getFetchedServerEntity(name, type).isPresent(); } - public Optional getServerManageable(String name, String type) { - return serverManageableStream().filter(manageable -> manageable.is(name, type)).findFirst(); + public Optional getFetchedServerEntity(String name, String type) { + return fetchedServerEntityStream().filter(serverEntity -> serverEntity.is(name, type)).findFirst(); } @Override @@ -216,7 +220,9 @@ public boolean equals(Object o) { if (!connections.equals(client.connections)) return false; if (!clientIdentifier.equals(client.clientIdentifier)) return false; - return hostName != null ? hostName.equals(client.hostName) : client.hostName == null; + if (!tags.equals(client.tags)) return false; + if (hostName != null ? !hostName.equals(client.hostName) : client.hostName != null) return false; + return managementRegistry != null ? managementRegistry.equals(client.managementRegistry) : client.managementRegistry == null; } @@ -225,7 +231,9 @@ public int hashCode() { int result = super.hashCode(); result = 31 * result + connections.hashCode(); result = 31 * result + clientIdentifier.hashCode(); + result = 31 * result + tags.hashCode(); result = 31 * result + (hostName != null ? hostName.hashCode() : 0); + result = 31 * result + (managementRegistry != null ? managementRegistry.hashCode() : 0); return result; } @@ -241,6 +249,7 @@ public Map toMap() { map.put("hostName", getHostName()); map.put("tags", tags); map.put("connections", connectionStream().sorted((o1, o2) -> o1.getId().compareTo(o2.getId())).map(Connection::toMap).collect(Collectors.toList())); + map.put("managementRegistry", managementRegistry == null ? null : managementRegistry.toMap()); return map; } diff --git a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Cluster.java b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Cluster.java index 37bfdc9258..9feccc3dcf 100644 --- a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Cluster.java +++ b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Cluster.java @@ -128,12 +128,8 @@ public Optional removeStripe(String id) { return stripe; } - public Optional getManageable(Context context) { - Optional manageable = getStripe(context).flatMap(s -> s.getActiveManageable(context)); - if (manageable.isPresent()) { - return manageable; - } - return getClient(context).flatMap(c -> c.getManageable(context)); + public Optional getServerEntity(Context context) { + return getStripe(context).flatMap(s -> s.getServerEntity(context)); } public Optional getServer(Context context) { @@ -146,13 +142,10 @@ public List getNodes(Context context) { nodes.add(stripe1); stripe1.getServer(context).ifPresent(server -> { nodes.add(server); - server.getManageable(context).ifPresent(nodes::add); + server.getServerEntity(context).ifPresent(nodes::add); }); }); - getClient(context).ifPresent(client -> { - nodes.add(client); - client.getManageable(context).ifPresent(nodes::add); - }); + getClient(context).ifPresent(nodes::add); return nodes; } @@ -165,16 +158,8 @@ public String getPath(Context context) { return sb.toString(); } - public Stream allManageableStream() { - return Stream.concat(serverManageableStream(), clientManageableStream()); - } - - public Stream serverManageableStream() { - return stripeStream().flatMap(Stripe::activeManageableStream); - } - - public Stream clientManageableStream() { - return clientStream().flatMap(Client::manageableStream); + public Stream serverEntityStream() { + return stripeStream().flatMap(Stripe::serverEntityStream); } public Stream serverStream() { diff --git a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Connection.java b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Connection.java index 8a3ad11b0a..36fc113529 100644 --- a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Connection.java +++ b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Connection.java @@ -34,7 +34,7 @@ public final class Connection extends AbstractNode implements Serializab public static final String KEY = "connectionId"; - private final Collection manageableIds = new ConcurrentSkipListSet<>(); + private final Collection serverEntityIds = new ConcurrentSkipListSet<>(); private final Endpoint clientEndpoint; private final String stripeId; private final String serverId; @@ -77,19 +77,19 @@ public Optional getServer() { } } - public Stream serverManageableStream() { + public Stream fetchedServerEntityStream() { return getServer() - .map(server -> manageableIds.stream() - .map(server::getManageable) + .map(server -> serverEntityIds.stream() + .map(server::getServerEntity) .filter(Optional::isPresent) .map(Optional::get)) .orElse(Stream.empty()); } - public int getServerManageableCount() { + public int getFetchedServerEntityCount() { return getServer() - .map(server -> manageableIds.stream() - .map(server::getManageable) + .map(server -> serverEntityIds.stream() + .map(server::getServerEntity) .filter(Optional::isPresent) .count()) .orElse(0L).intValue(); @@ -118,7 +118,7 @@ public boolean equals(Object o) { Connection that = (Connection) o; - if (!manageableIds.equals(that.manageableIds)) return false; + if (!serverEntityIds.equals(that.serverEntityIds)) return false; if (!clientEndpoint.equals(that.clientEndpoint)) return false; if (stripeId != null ? !stripeId.equals(that.stripeId) : that.stripeId != null) return false; return serverId != null ? serverId.equals(that.serverId) : that.serverId == null; @@ -131,7 +131,7 @@ public int hashCode() { // and can be different whether we opened/closed several connections in our different tests //int result = super.hashCode(); int result = 0; - result = 31 * result + manageableIds.hashCode(); + result = 31 * result + serverEntityIds.hashCode(); result = 31 * result + clientEndpoint.hashCode(); result = 31 * result + (stripeId != null ? stripeId.hashCode() : 0); result = 31 * result + (serverId != null ? serverId.hashCode() : 0); @@ -145,34 +145,30 @@ public Map toMap() { map.put("clientEndpoint", clientEndpoint.toMap()); map.put("stripeId", this.stripeId); map.put("serverId", this.serverId); - map.put("manageableIds", this.manageableIds); + map.put("serverEntityIds", this.serverEntityIds); return map; } - public void disconnectServerManageable(String name, String type) { - manageableIds.remove(Manageable.key(name, type)); + public void unfetchServerEntity(String name, String type) { + serverEntityIds.remove(ServerEntity.key(name, type)); } - public boolean connectServerManageable(Manageable manageable) { + public boolean fetchServerEntity(ServerEntity serverEntity) { if (!isConnected()) { throw new IllegalStateException("not connnected"); } - if (!(manageable.getParent() instanceof Server)) { - throw new IllegalArgumentException(String.valueOf(manageable.getParent())); + if (!(serverEntity.getParent() instanceof Server)) { + throw new IllegalArgumentException(String.valueOf(serverEntity.getParent())); } - Server server = (Server) manageable.getParent(); + Server server = (Server) serverEntity.getParent(); if (server != getServer().get()) { - throw new IllegalStateException("wrong server manageable"); + throw new IllegalStateException("wrong server serverEntity"); } - return manageableIds.add(manageable.getId()); + return serverEntityIds.add(serverEntity.getId()); } - public boolean isConnectedToServerManageable(String name, String type) { - return serverManageableStream().filter(manageable -> manageable.is(name, type)).findFirst().isPresent(); - } - - public boolean isConnectedToActiveServer() { - return getServer().filter(Server::isActive).isPresent(); + public boolean hasFetchedServerEntity(String name, String type) { + return fetchedServerEntityStream().filter(serverEntity -> serverEntity.is(name, type)).findFirst().isPresent(); } public boolean isConnectedTo(Server server) { diff --git a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/ManageableContainer.java b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/ManageableContainer.java deleted file mode 100644 index ed638f09f3..0000000000 --- a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/ManageableContainer.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Terracotta, 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 org.terracotta.management.model.cluster; - -import org.terracotta.management.model.context.Context; - -import java.util.Map; -import java.util.Optional; -import java.util.stream.Stream; - -/** - * @author Mathieu Carbou - */ -public interface ManageableContainer { - Map getManageables(); - - int getManageableCount(); - - B addManageable(Manageable manageable); - - Stream manageableStream(); - - Optional getManageable(Context context); - - Optional getManageable(String id); - - Optional getManageable(String name, String type); - - boolean hasManageable(String name, String type); - - Optional removeManageable(String id); - - Stream manageableStream(String type); -} diff --git a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Manageable.java b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/ManagementRegistry.java similarity index 57% rename from cluster-topology/src/main/java/org/terracotta/management/model/cluster/Manageable.java rename to cluster-topology/src/main/java/org/terracotta/management/model/cluster/ManagementRegistry.java index 19c1a38777..8a3a944ba6 100644 --- a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Manageable.java +++ b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/ManagementRegistry.java @@ -23,7 +23,6 @@ import org.terracotta.management.model.capabilities.descriptors.Settings; import org.terracotta.management.model.capabilities.descriptors.StatisticDescriptor; import org.terracotta.management.model.capabilities.descriptors.StatisticDescriptorCategory; -import org.terracotta.management.model.context.Context; import org.terracotta.management.model.context.ContextContainer; import java.io.Serializable; @@ -39,42 +38,33 @@ /** * @author Mathieu Carbou */ -public final class Manageable extends AbstractNode implements Serializable { +public final class ManagementRegistry implements Serializable { private static final long serialVersionUID = 1; - public static final String KEY = "manageableId"; - public static final String TYPE_KEY = "manageableType"; - public static final String NAME_KEY = "manageableName"; + private final ContextContainer contextContainer; + private final Map capabilities = new LinkedHashMap<>(); - private final String type; // type (service, client entity, server entity, etc) - private final String name; // type (entity type name) - private ContextContainer contextContainer; // management registry output - private Map capabilities = new LinkedHashMap<>(); - - // matches management registry config, or entity id, or service type - private Manageable(String id, String name, String type) { - super(id); - this.type = Objects.requireNonNull(type); - this.name = Objects.requireNonNull(name); + private ManagementRegistry(ContextContainer contextContainer) { + this.contextContainer = Objects.requireNonNull(contextContainer); } - public Manageable setCapabilities(Collection capabilities) { + public ManagementRegistry setCapabilities(Collection capabilities) { this.capabilities.clear(); capabilities.forEach(this::addCapability); return this; } - public Manageable setCapabilities(Capability... capabilities) { + public ManagementRegistry setCapabilities(Capability... capabilities) { return setCapabilities(Arrays.asList(capabilities)); } - public Manageable addCapability(Capability capability) { + public ManagementRegistry addCapability(Capability capability) { this.capabilities.put(capability.getName(), capability); return this; } - public Manageable addCapabilities(Capability... capabilities) { + public ManagementRegistry addCapabilities(Capability... capabilities) { for (Capability capability : capabilities) { addCapability(capability); } @@ -85,131 +75,54 @@ public Collection getCapabilities() { return capabilities.values(); } - public Capability findCapability(String id) { + public Capability findCapability(String capabilityName) { for (Capability capability : capabilities.values()) { - if (capability.getName().equals(name)) { + if (capability.getName().equals(capabilityName)) { return capability; } } return null; } - public Manageable setContextContainer(ContextContainer contextContainer) { - this.contextContainer = contextContainer; - return this; - } - public ContextContainer getContextContainer() { return contextContainer; } - public String getType() { - return type; - } - - public boolean isType(String type) { - return this.type.equals(type); - } - - public String getName() { - return name; - } - - @Override - public Context getContext() { - Context context = super.getContext() - .with(NAME_KEY, name) - .with(TYPE_KEY, type); - return contextContainer == null ? context : context.with(contextContainer.getName(), contextContainer.getValue()); - } - - @Override - public void remove() { - Node parent = getParent(); - if (parent != null && parent instanceof ManageableContainer) { - ((ManageableContainer) parent).removeManageable(getId()); - } - } - - public T getContainer(Class type) { - return type.cast(getParent()); - } - - public Collection getAllCapabilityContexts(String capabilityName) { - Context thisContext = getContext(); - Capability capability = capabilities.get(capabilityName); - if (capability == null) { - throw new IllegalArgumentException(capabilityName); - } - - // get all attributes to make this capability works - Collection requiredAttributesNames = capability.getCapabilityContext().getRequiredAttributeNames(); - boolean addMainCtx = requiredAttributesNames.contains(contextContainer.getName()); - - Collection contexts = new ArrayList<>(contextContainer.getSubContexts().size()); - for (ContextContainer subCtx : contextContainer.getSubContexts()) { - if (requiredAttributesNames.contains(subCtx.getName())) { - Context ctx = thisContext.with(subCtx.getName(), subCtx.getValue()); - if (addMainCtx) { - ctx = ctx.with(contextContainer.getName(), contextContainer.getValue()); - } - contexts.add(ctx); - } - } - - return contexts; - } - - @Override - String getContextKey() { - return KEY; - } - - public boolean is(String name, String type) { - return this.name.equals(name) && this.type.equals(type); - } - @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - Manageable that = (Manageable) o; + ManagementRegistry that = (ManagementRegistry) o; - if (!type.equals(that.type)) return false; - if (!name.equals(that.name)) return false; - if (contextContainer != null ? !contextContainer.equals(that.contextContainer) : that.contextContainer != null) return false; - return capabilities != null ? capabilities.equals(that.capabilities) : that.capabilities == null; + if (!contextContainer.equals(that.contextContainer)) return false; + return capabilities.equals(that.capabilities); } @Override public int hashCode() { - int result = super.hashCode(); - result = 31 * result + type.hashCode(); - result = 31 * result + name.hashCode(); - result = 31 * result + (contextContainer != null ? contextContainer.hashCode() : 0); - result = 31 * result + (capabilities != null ? capabilities.hashCode() : 0); + int result = contextContainer.hashCode(); + result = 31 * result + capabilities.hashCode(); return result; } @Override + public String toString() { + return contextContainer.getValue(); + } + public Map toMap() { - Map map = super.toMap(); - map.put("type", getType()); - map.put("name", getName()); - if (contextContainer != null) { - map.put("contextContainer", toMap(contextContainer)); - } - map.put("capabilities", this.capabilities.values().stream().map(Manageable::toMap).collect(Collectors.toList())); + Map map = new LinkedHashMap<>(); + map.put("contextContainer", toMap(contextContainer)); + map.put("capabilities", this.capabilities.values().stream().map(ManagementRegistry::toMap).collect(Collectors.toList())); return map; } private static Map toMap(Capability capability) { Map map = new LinkedHashMap<>(); map.put("name", capability.getName()); - map.put("context", capability.getCapabilityContext().getAttributes().stream().map(Manageable::toMap).collect(Collectors.toList())); + map.put("context", capability.getCapabilityContext().getAttributes().stream().map(ManagementRegistry::toMap).collect(Collectors.toList())); List> descriptorList = new ArrayList<>(capability.getDescriptors().size()); map.put("descriptors", descriptorList); @@ -262,7 +175,7 @@ private static Map toMap(StatisticDescriptor descriptor) { private static Map toMap(StatisticDescriptorCategory descriptor) { Map map = new LinkedHashMap<>(); map.put("name", descriptor.getName()); - map.put("statistics", descriptor.getStatistics().stream().map(Manageable::toMap).collect(Collectors.toList())); + map.put("statistics", descriptor.getStatistics().stream().map(ManagementRegistry::toMap).collect(Collectors.toList())); return map; } @@ -270,7 +183,7 @@ private static Map toMap(CallDescriptor descriptor) { Map map = new LinkedHashMap<>(); map.put("name", descriptor.getName()); map.put("returnType", descriptor.getReturnType()); - map.put("parameters", descriptor.getParameters().stream().map(Manageable::toMap).collect(Collectors.toList())); + map.put("parameters", descriptor.getParameters().stream().map(ManagementRegistry::toMap).collect(Collectors.toList())); return map; } @@ -295,16 +208,12 @@ private static Map toMap(CallDescriptor.Parameter parameter) { private static Map toMap(ContextContainer contextContainer) { Map map = new LinkedHashMap<>(); map.put(contextContainer.getName(), contextContainer.getValue()); - map.put("subContexts", contextContainer.getSubContexts().stream().map(Manageable::toMap).collect(Collectors.toList())); + map.put("subContexts", contextContainer.getSubContexts().stream().map(ManagementRegistry::toMap).collect(Collectors.toList())); return map; } - public static Manageable create(String manageableName, String type) { - return new Manageable(key(manageableName, type), manageableName, type); - } - - public static String key(String manageableName, String type) { - return manageableName + ":" + type; + public static ManagementRegistry create(ContextContainer contextContainer) { + return new ManagementRegistry(contextContainer); } } diff --git a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/NodeWithManageable.java b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/NodeWithManageable.java deleted file mode 100644 index c83dca6a15..0000000000 --- a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/NodeWithManageable.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Terracotta, 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 org.terracotta.management.model.cluster; - -/** - * @author Mathieu Carbou - */ -public interface NodeWithManageable extends Node, ManageableContainer { - -} diff --git a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Server.java b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Server.java index 7a7e1c70a0..00ecfc9dd0 100644 --- a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Server.java +++ b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Server.java @@ -15,23 +15,31 @@ */ package org.terracotta.management.model.cluster; +import org.terracotta.management.model.Objects; import org.terracotta.management.model.context.Context; import java.io.Serializable; import java.time.Clock; import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * @author Mathieu Carbou */ -public final class Server extends AbstractNodeWithManageable implements Serializable { +public final class Server extends AbstractNode implements Serializable { private static final long serialVersionUID = 1; public static final String KEY = "serverId"; public static final String NAME_KEY = "serverName"; + private final ConcurrentMap serverEntities = new ConcurrentHashMap<>(); private final String serverName; // matches xml config + private String hostName; // matches xml config private String hostAddress; // matches xml config private String bindAddress; // matches xml config @@ -46,7 +54,7 @@ public final class Server extends AbstractNodeWithManageable imp private Server(String serverId, String serverName) { super(serverId); - this.serverName = serverName; + this.serverName = Objects.requireNonNull(serverName); } public boolean isActive() { @@ -183,6 +191,62 @@ public Server setActivateTime(long activateTime) { return this; } + public final Map getServerEntities() { + return serverEntities; + } + + public final int getServerEntityCount() { + return serverEntities.size(); + } + + public final Stream serverEntityStream() { + return serverEntities.values().stream(); + } + + public final Server addServerEntity(ServerEntity serverEntity) { + // ServerEntityId are unique per their ID but also per their combination of (type + name) + for (ServerEntity m : serverEntities.values()) { + if (m.is(serverEntity.getType(), serverEntity.getName())) { + throw new IllegalArgumentException("Duplicate serverEntity: type=" + serverEntity.getType() + ", name=" + serverEntity.getName()); + } + } + if (serverEntities.putIfAbsent(serverEntity.getId(), serverEntity) != null) { + throw new IllegalArgumentException("Duplicate serverEntity: " + serverEntity.getId()); + } + serverEntity.setParent(this); + return this; + } + + public final Optional getServerEntity(Context context) { + return getServerEntity(context.get(ServerEntity.KEY)); + } + + public final Optional getServerEntity(String id) { + return id == null ? Optional.empty() : Optional.ofNullable(serverEntities.get(id)); + } + + public final Optional getServerEntity(String name, String type) { + return serverEntityStream().filter(serverEntity -> serverEntity.is(name, type)).findFirst(); + } + + public final boolean hasServerEntity(String name, String type) { + return getServerEntity(name, type).isPresent(); + } + + public final Optional removeServerEntity(String id) { + Optional serverEntity = getServerEntity(id); + serverEntity.ifPresent(m -> { + if (serverEntities.remove(id, m)) { + m.detach(); + } + }); + return serverEntity; + } + + public final Stream serverEntityStream(String type) { + return serverEntityStream().filter(serverEntity -> serverEntity.isType(type)); + } + @Override public void remove() { Stripe parent = getParent(); @@ -201,11 +265,14 @@ public boolean equals(Object o) { if (bindPort != server.bindPort) return false; if (groupPort != server.groupPort) return false; - if (activateTime != server.activateTime) return false; if (startTime != server.startTime) return false; + if (activateTime != server.activateTime) return false; + if (!serverEntities.equals(server.serverEntities)) return false; + if (serverName != null ? !serverName.equals(server.serverName) : server.serverName != null) return false; if (hostName != null ? !hostName.equals(server.hostName) : server.hostName != null) return false; if (hostAddress != null ? !hostAddress.equals(server.hostAddress) : server.hostAddress != null) return false; if (bindAddress != null ? !bindAddress.equals(server.bindAddress) : server.bindAddress != null) return false; + if (state != server.state) return false; if (version != null ? !version.equals(server.version) : server.version != null) return false; return buildId != null ? buildId.equals(server.buildId) : server.buildId == null; @@ -214,21 +281,25 @@ public boolean equals(Object o) { @Override public int hashCode() { int result = super.hashCode(); + result = 31 * result + serverEntities.hashCode(); + result = 31 * result + (serverName != null ? serverName.hashCode() : 0); result = 31 * result + (hostName != null ? hostName.hashCode() : 0); result = 31 * result + (hostAddress != null ? hostAddress.hashCode() : 0); result = 31 * result + (bindAddress != null ? bindAddress.hashCode() : 0); result = 31 * result + bindPort; result = 31 * result + groupPort; + result = 31 * result + (state != null ? state.hashCode() : 0); result = 31 * result + (version != null ? version.hashCode() : 0); result = 31 * result + (buildId != null ? buildId.hashCode() : 0); - result = 31 * result + (int) (activateTime ^ (activateTime >>> 32)); result = 31 * result + (int) (startTime ^ (startTime >>> 32)); + result = 31 * result + (int) (activateTime ^ (activateTime >>> 32)); return result; } @Override public Map toMap() { Map map = super.toMap(); + map.put("serverEntities", serverEntityStream().sorted((o1, o2) -> o1.getId().compareTo(o2.getId())).map(ServerEntity::toMap).collect(Collectors.toList())); map.put("serverName", this.getServerName()); map.put("hostName", this.hostName); map.put("hostAddress", this.hostAddress); diff --git a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/ServerEntity.java b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/ServerEntity.java new file mode 100644 index 0000000000..b004261173 --- /dev/null +++ b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/ServerEntity.java @@ -0,0 +1,134 @@ +/* + * Copyright Terracotta, 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 org.terracotta.management.model.cluster; + +import org.terracotta.management.model.context.Context; + +import java.io.Serializable; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +/** + * @author Mathieu Carbou + */ +public final class ServerEntity extends AbstractNode implements Serializable { + + private static final long serialVersionUID = 1; + + public static final String KEY = "entityId"; + public static final String TYPE_KEY = "entityType"; + public static final String NAME_KEY = "entityName"; + + private final String type; // type (service, client entity, server entity, etc) + private final String name; // type (entity type name) + private ManagementRegistry managementRegistry; + + // matches management registry config, or entity id, or service type + private ServerEntity(String id, String name, String type) { + super(id); + this.type = Objects.requireNonNull(type); + this.name = Objects.requireNonNull(name); + } + + public Optional getManagementRegistry() { + return Optional.ofNullable(managementRegistry); + } + + public ServerEntity setManagementRegistry(ManagementRegistry managementRegistry) { + this.managementRegistry = managementRegistry; + return this; + } + + public String getType() { + return type; + } + + public boolean isType(String type) { + return this.type.equals(type); + } + + public String getName() { + return name; + } + + @Override + public Context getContext() { + return super.getContext().with(NAME_KEY, name).with(TYPE_KEY, type); + } + + @Override + public void remove() { + Server parent = getParent(); + if (parent != null) { + parent.removeServerEntity(getId()); + } + } + + public Server getServer() { + return getParent(); + } + + @Override + String getContextKey() { + return KEY; + } + + public boolean is(String name, String type) { + return this.name.equals(name) && this.type.equals(type); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + ServerEntity that = (ServerEntity) o; + + if (!type.equals(that.type)) return false; + if (!name.equals(that.name)) return false; + return managementRegistry != null ? managementRegistry.equals(that.managementRegistry) : that.managementRegistry == null; + + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + type.hashCode(); + result = 31 * result + name.hashCode(); + result = 31 * result + (managementRegistry != null ? managementRegistry.hashCode() : 0); + return result; + } + + @Override + public Map toMap() { + Map map = super.toMap(); + map.put("type", getType()); + map.put("name", getName()); + map.put("managementRegistry", managementRegistry == null ? null : managementRegistry.toMap()); + return map; + } + + public static ServerEntity create(String serverEntityName, String type) { + return new ServerEntity(key(serverEntityName, type), serverEntityName, type); + } + + public static String key(String serverEntityName, String type) { + return serverEntityName + ":" + type; + } + +} diff --git a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Stripe.java b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Stripe.java index 361c612993..a9acd52a1f 100644 --- a/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Stripe.java +++ b/cluster-topology/src/main/java/org/terracotta/management/model/cluster/Stripe.java @@ -110,20 +110,16 @@ public Optional removeServer(String id) { return server; } - public Optional getActiveManageable(Context context) { - return getActiveServer().flatMap(s -> s.getManageable(context)); + public Optional getServerEntity(Context context) { + return getActiveServer().flatMap(s -> s.getServerEntity(context)); } - public Optional getActiveManageable(String name, String type) { - return getActiveServer().flatMap(s -> s.getManageable(name, type)); + public Optional getServerEntity(String name, String type) { + return getActiveServer().flatMap(s -> s.getServerEntity(name, type)); } - public Stream manageableStream() { - return serverStream().flatMap(NodeWithManageable::manageableStream); - } - - public Stream activeManageableStream() { - return getActiveServer().map(NodeWithManageable::manageableStream).orElse(Stream.empty()); + public Stream serverEntityStream() { + return getActiveServer().map(Server::serverEntityStream).orElse(Stream.empty()); } @Override diff --git a/cluster-topology/src/test/java/org/terracotta/management/model/cluster/AbstractTest.java b/cluster-topology/src/test/java/org/terracotta/management/model/cluster/AbstractTest.java index 3f0c1021d5..d72923a0e6 100644 --- a/cluster-topology/src/test/java/org/terracotta/management/model/cluster/AbstractTest.java +++ b/cluster-topology/src/test/java/org/terracotta/management/model/cluster/AbstractTest.java @@ -32,17 +32,22 @@ public abstract class AbstractTest { protected Cluster cluster1; protected Cluster cluster2; - protected Manageable ehcache_client_entity; - protected Manageable ehcache_server_entity; + protected ServerEntity ehcache_server_entity; protected Capability action; - protected ContextContainer contextContainer; + protected ContextContainer serverContextContainer; + protected ContextContainer clientContextContainer; + protected Client client; private ClientIdentifier clientIdentifier; @Before public void createClusters() { action = new DefaultCapability("ActionCapability", new CapabilityContext()); - contextContainer = new ContextContainer("cacheManagerName", "cache-manager-1", new ContextContainer("cacheName", "my-cache")); + clientContextContainer = new ContextContainer("cacheManagerName", "cache-manager-1", new ContextContainer("cacheName", "my-cache")); + serverContextContainer = new ContextContainer("entityName", "ehcache-entity-name-1"); clientIdentifier = ClientIdentifier.create("ehcache", "client1"); + ehcache_server_entity = ServerEntity.create("ehcache-entity-name-1", "org.ehcache.clustered.client.internal.EhcacheClientEntity") + .setManagementRegistry(ManagementRegistry.create(serverContextContainer) + .addCapabilities(action)); cluster1 = Cluster.create() .addStripe(Stripe.create("stripe-1") @@ -51,11 +56,7 @@ public void createClusters() { .setBindAddress("0.0.0.0") .setBindPort(8881) .setState(ServerState.ACTIVE) - .addManageable(ehcache_server_entity = Manageable.create(contextContainer.getValue(), "org.ehcache.clustered.client.internal.EhcacheClientEntity") - .setContextContainer(contextContainer) - .addCapability(action)) - .addManageable(Manageable.create("service-1", "SERVICE") - .setContextContainer(new ContextContainer("serviceName", "task-service")))) + .addServerEntity(ehcache_server_entity)) .addServer(Server.create("server-2") .setHostName("hostname-2") .setBindAddress("0.0.0.0") @@ -67,19 +68,16 @@ public void createClusters() { .setBindAddress("0.0.0.0") .setBindPort(8881) .setState(ServerState.ACTIVE) - .addManageable(Manageable.create(contextContainer.getValue(), "org.ehcache.clustered.client.internal.EhcacheClientEntity") - .setContextContainer(new ContextContainer("cacheManagerName", "cache-manager-1")) - .addCapability(action)) - .addManageable(Manageable.create("service-1", "SERVICE") - .setContextContainer(new ContextContainer("serviceName", "task-service")))) + .addServerEntity(ServerEntity.create("ehcache-entity-name-1", "org.ehcache.clustered.client.internal.EhcacheClientEntity") + .setManagementRegistry(ManagementRegistry.create(serverContextContainer) + .addCapabilities(action)))) .addServer(Server.create("server-2") .setHostName("hostname-4") .setBindAddress("0.0.0.0") .setBindPort(8881) .setState(ServerState.PASSIVE))) - .addClient(Client.create("12345@127.0.0.1:ehcache:uid") - .addManageable(ehcache_client_entity = Manageable.create(contextContainer.getValue(), "org.ehcache.clustered.client.internal.EhcacheClientEntity") - .setContextContainer(contextContainer) + .addClient(client = Client.create("12345@127.0.0.1:ehcache:uid") + .setManagementRegistry(ManagementRegistry.create(clientContextContainer) .addCapability(action))); Client client1 = cluster1.getClient("12345@127.0.0.1:ehcache:uid").get(); @@ -101,11 +99,9 @@ public void createClusters() { .setBindAddress("0.0.0.0") .setBindPort(8881) .setState(ServerState.ACTIVE) - .addManageable(ehcache_server_entity = Manageable.create(contextContainer.getValue(), "org.ehcache.clustered.client.internal.EhcacheClientEntity") - .setContextContainer(contextContainer) - .addCapability(action)) - .addManageable(Manageable.create("service-1", "SERVICE") - .setContextContainer(new ContextContainer("serviceName", "task-service")))) + .addServerEntity(ServerEntity.create("ehcache-entity-name-1", "org.ehcache.clustered.client.internal.EhcacheClientEntity") + .setManagementRegistry(ManagementRegistry.create(serverContextContainer) + .addCapabilities(action)))) .addServer(Server.create("server-2") .setHostName("hostname-2") .setBindAddress("0.0.0.0") @@ -117,19 +113,16 @@ public void createClusters() { .setBindAddress("0.0.0.0") .setBindPort(8881) .setState(ServerState.ACTIVE) - .addManageable(Manageable.create(contextContainer.getValue(), "org.ehcache.clustered.client.internal.EhcacheClientEntity") - .setContextContainer(new ContextContainer("cacheManagerName", "cache-manager-1")) - .addCapability(action)) - .addManageable(Manageable.create("service-1", "SERVICE") - .setContextContainer(new ContextContainer("serviceName", "task-service")))) + .addServerEntity(ServerEntity.create("ehcache-entity-name-1", "org.ehcache.clustered.client.internal.EhcacheClientEntity") + .setManagementRegistry(ManagementRegistry.create(serverContextContainer) + .addCapabilities(action)))) .addServer(Server.create("server-2") .setHostName("hostname-4") .setBindAddress("0.0.0.0") .setBindPort(8881) .setState(ServerState.PASSIVE))) .addClient(Client.create("12345@127.0.0.1:ehcache:uid") - .addManageable(ehcache_client_entity = Manageable.create(contextContainer.getValue(), "org.ehcache.clustered.client.internal.EhcacheClientEntity") - .setContextContainer(contextContainer) + .setManagementRegistry(ManagementRegistry.create(clientContextContainer) .addCapability(action))); Client client2 = cluster2.getClient("12345@127.0.0.1:ehcache:uid").get(); diff --git a/cluster-topology/src/test/java/org/terracotta/management/model/cluster/ClusterTest.java b/cluster-topology/src/test/java/org/terracotta/management/model/cluster/ClusterTest.java index 1551a34843..fc80b44176 100644 --- a/cluster-topology/src/test/java/org/terracotta/management/model/cluster/ClusterTest.java +++ b/cluster-topology/src/test/java/org/terracotta/management/model/cluster/ClusterTest.java @@ -70,25 +70,20 @@ public void test_equals_hashcode() { @Test public void test_nodes_path() throws UnknownHostException { - assertEquals(3, cluster1.getManageable(ehcache_server_entity.getContext()).get().getNodePath().size()); + assertEquals(3, cluster1.getServerEntity(ehcache_server_entity.getContext()).get().getNodePath().size()); assertEquals( - "stripe-1/server-1/cache-manager-1:org.ehcache.clustered.client.internal.EhcacheClientEntity", - cluster1.getManageable(ehcache_server_entity.getContext()).get().getStringPath()); + "stripe-1/server-1/ehcache-entity-name-1:org.ehcache.clustered.client.internal.EhcacheClientEntity", + cluster1.getServerEntity(ehcache_server_entity.getContext()).get().getStringPath()); - assertEquals(5, ehcache_client_entity.getContext().size()); - - assertEquals(2, cluster1.getManageable(ehcache_client_entity.getContext()).get().getNodePath().size()); - assertEquals( - "12345@127.0.0.1:ehcache:uid/cache-manager-1:org.ehcache.clustered.client.internal.EhcacheClientEntity", - cluster1.getManageable(ehcache_client_entity.getContext()).get().getStringPath()); + assertEquals(6, ehcache_server_entity.getContext().size()); assertEquals(3, cluster1.getNodes(ehcache_server_entity.getContext()).size()); - assertEquals("[stripe-1, server-1, cache-manager-1:org.ehcache.clustered.client.internal.EhcacheClientEntity]", cluster1.getNodes(ehcache_server_entity.getContext()).toString()); + assertEquals("[stripe-1, server-1, ehcache-entity-name-1:org.ehcache.clustered.client.internal.EhcacheClientEntity]", cluster1.getNodes(ehcache_server_entity.getContext()).toString()); - assertEquals(2, cluster1.getNodes(ehcache_client_entity.getContext()).size()); + assertEquals(1, cluster1.getNodes(client.getContext()).size()); assertEquals( - "[12345@127.0.0.1:ehcache:uid, cache-manager-1:org.ehcache.clustered.client.internal.EhcacheClientEntity]", - cluster1.getNodes(ehcache_client_entity.getContext()).toString()); + "[12345@127.0.0.1:ehcache:uid]", + cluster1.getNodes(client.getContext()).toString()); } @Test @@ -184,30 +179,30 @@ public void test_add_remove_connection() { } @Test - public void test_add_remove_manageable() { + public void test_add_remove_server_entity() { System.out.println(ClientIdentifier.discoverHostName()); - Client client = cluster1.getClient("12345@127.0.0.1:ehcache:uid").get(); + Server server = cluster1.stripeStream().findFirst().get().getActiveServer().get(); - assertEquals(1, client.getManageables().size()); + assertEquals(1, server.getServerEntityCount()); try { - client.addManageable(Manageable.create(contextContainer.getValue(), "org.ehcache.clustered.client.internal.EhcacheClientEntity").setContextContainer(contextContainer)); + server.addServerEntity(ServerEntity.create(serverContextContainer.getValue(), "org.ehcache.clustered.client.internal.EhcacheClientEntity")); fail(); } catch (Exception e) { assertEquals(IllegalArgumentException.class, e.getClass()); } - assertEquals(1, client.getManageables().size()); + assertEquals(1, server.getServerEntityCount()); - client.addManageable(Manageable.create("other-cm-4", "org.ehcache.clustered.client.internal.EhcacheClientEntity").setContextContainer(contextContainer)); - client.addManageable(Manageable.create("name", "OTHER_TYPE").setContextContainer(contextContainer)); + server.addServerEntity(ServerEntity.create("other-cm-4", "org.ehcache.clustered.client.internal.EhcacheClientEntity")); + server.addServerEntity(ServerEntity.create("name", "OTHER_TYPE")); - assertEquals(3, client.getManageables().size()); + assertEquals(3, server.getServerEntityCount()); - assertTrue(client.removeManageable("other-cm-4:" + "org.ehcache.clustered.client.internal.EhcacheClientEntity").isPresent()); - assertFalse(client.getManageable("other-cm-4:" + "org.ehcache.clustered.client.internal.EhcacheClientEntity").isPresent()); - assertEquals(2, client.getManageables().size()); + assertTrue(server.removeServerEntity("other-cm-4:" + "org.ehcache.clustered.client.internal.EhcacheClientEntity").isPresent()); + assertFalse(server.getServerEntity("other-cm-4:" + "org.ehcache.clustered.client.internal.EhcacheClientEntity").isPresent()); + assertEquals(2, server.getServerEntityCount()); } @Test diff --git a/cluster-topology/src/test/resources/cluster.json b/cluster-topology/src/test/resources/cluster.json index b35eff8ae1..41298dd8e5 100644 --- a/cluster-topology/src/test/resources/cluster.json +++ b/cluster-topology/src/test/resources/cluster.json @@ -4,31 +4,21 @@ "name" : "stripe-1", "servers" : [ { "id" : "server-1", - "manageables" : [ { - "id" : "cache-manager-1:org.ehcache.clustered.client.internal.EhcacheClientEntity", + "serverEntities" : [ { + "id" : "ehcache-entity-name-1:org.ehcache.clustered.client.internal.EhcacheClientEntity", "type" : "org.ehcache.clustered.client.internal.EhcacheClientEntity", - "name" : "cache-manager-1", - "contextContainer" : { - "cacheManagerName" : "cache-manager-1", - "subContexts" : [ { - "cacheName" : "my-cache", + "name" : "ehcache-entity-name-1", + "managementRegistry" : { + "contextContainer" : { + "entityName" : "ehcache-entity-name-1", "subContexts" : [ ] + }, + "capabilities" : [ { + "name" : "ActionCapability", + "context" : [ ], + "descriptors" : [ ] } ] - }, - "capabilities" : [ { - "name" : "ActionCapability", - "context" : [ ], - "descriptors" : [ ] - } ] - }, { - "id" : "service-1:SERVICE", - "type" : "SERVICE", - "name" : "service-1", - "contextContainer" : { - "serviceName" : "task-service", - "subContexts" : [ ] - }, - "capabilities" : [ ] + } } ], "serverName" : "server-1", "hostName" : "hostname-1", @@ -44,7 +34,7 @@ "activateTime" : 0 }, { "id" : "server-2", - "manageables" : [ ], + "serverEntities" : [ ], "serverName" : "server-2", "hostName" : "hostname-2", "hostAddress" : null, @@ -63,28 +53,21 @@ "name" : "stripe-2", "servers" : [ { "id" : "server-1", - "manageables" : [ { - "id" : "cache-manager-1:org.ehcache.clustered.client.internal.EhcacheClientEntity", + "serverEntities" : [ { + "id" : "ehcache-entity-name-1:org.ehcache.clustered.client.internal.EhcacheClientEntity", "type" : "org.ehcache.clustered.client.internal.EhcacheClientEntity", - "name" : "cache-manager-1", - "contextContainer" : { - "cacheManagerName" : "cache-manager-1", - "subContexts" : [ ] - }, - "capabilities" : [ { - "name" : "ActionCapability", - "context" : [ ], - "descriptors" : [ ] - } ] - }, { - "id" : "service-1:SERVICE", - "type" : "SERVICE", - "name" : "service-1", - "contextContainer" : { - "serviceName" : "task-service", - "subContexts" : [ ] - }, - "capabilities" : [ ] + "name" : "ehcache-entity-name-1", + "managementRegistry" : { + "contextContainer" : { + "entityName" : "ehcache-entity-name-1", + "subContexts" : [ ] + }, + "capabilities" : [ { + "name" : "ActionCapability", + "context" : [ ], + "descriptors" : [ ] + } ] + } } ], "serverName" : "server-1", "hostName" : "hostname-3", @@ -100,7 +83,7 @@ "activateTime" : 0 }, { "id" : "server-2", - "manageables" : [ ], + "serverEntities" : [ ], "serverName" : "server-2", "hostName" : "hostname-4", "hostAddress" : null, @@ -117,23 +100,6 @@ } ], "clients" : [ { "id" : "12345@127.0.0.1:ehcache:uid", - "manageables" : [ { - "id" : "cache-manager-1:org.ehcache.clustered.client.internal.EhcacheClientEntity", - "type" : "org.ehcache.clustered.client.internal.EhcacheClientEntity", - "name" : "cache-manager-1", - "contextContainer" : { - "cacheManagerName" : "cache-manager-1", - "subContexts" : [ { - "cacheName" : "my-cache", - "subContexts" : [ ] - } ] - }, - "capabilities" : [ { - "name" : "ActionCapability", - "context" : [ ], - "descriptors" : [ ] - } ] - } ], "pid" : 12345, "hostAddress" : "127.0.0.1", "name" : "ehcache", @@ -151,7 +117,7 @@ }, "stripeId" : "stripe-1", "serverId" : "server-1", - "manageableIds" : [ ] + "serverEntityIds" : [ ] }, { "id" : "uid:stripe-2:server-1:10.10.10.10:3457", "logicalConnectionUid" : "uid", @@ -161,7 +127,21 @@ }, "stripeId" : "stripe-2", "serverId" : "server-1", - "manageableIds" : [ ] - } ] + "serverEntityIds" : [ ] + } ], + "managementRegistry" : { + "contextContainer" : { + "cacheManagerName" : "cache-manager-1", + "subContexts" : [ { + "cacheName" : "my-cache", + "subContexts" : [ ] + } ] + }, + "capabilities" : [ { + "name" : "ActionCapability", + "context" : [ ], + "descriptors" : [ ] + } ] + } } ] } \ No newline at end of file diff --git a/management-entity/management-entity-server/src/main/java/org/terracotta/management/entity/server/ManagementAgentImpl.java b/management-entity/management-entity-server/src/main/java/org/terracotta/management/entity/server/ManagementAgentImpl.java index 47bdb0bcd8..d940c34da3 100644 --- a/management-entity/management-entity-server/src/main/java/org/terracotta/management/entity/server/ManagementAgentImpl.java +++ b/management-entity/management-entity-server/src/main/java/org/terracotta/management/entity/server/ManagementAgentImpl.java @@ -40,9 +40,9 @@ * Produces: *

* * @author Mathieu Carbou @@ -67,10 +67,8 @@ public Future getClientIdentifier(@ClientId Object clientDescr @Override public Future exposeManagementMetadata(@ClientId Object clientDescriptor, ContextContainer contextContainer, Capability... capabilities) { Utils.getClientIdentifier(consumer, clientDescriptor).ifPresent(clientIdentifier -> { - String name = contextContainer.getName() + ":" + contextContainer.getValue(); - producer.addNode(array("management", "clients", clientIdentifier.getClientId()), name, null); - producer.addNode(array("management", "clients", clientIdentifier.getClientId(), name), "contextContainer", contextContainer); - producer.addNode(array("management", "clients", clientIdentifier.getClientId(), name), "capabilities", capabilities); + producer.addNode(array("management", "clients", clientIdentifier.getClientId(), "registry"), "contextContainer", contextContainer); + producer.addNode(array("management", "clients", clientIdentifier.getClientId(), "registry"), "capabilities", capabilities); }); return CompletableFuture.completedFuture(null); } diff --git a/management-entity/management-entity-server/src/main/java/org/terracotta/management/entity/server/ManagementAgentServerEntity.java b/management-entity/management-entity-server/src/main/java/org/terracotta/management/entity/server/ManagementAgentServerEntity.java index 95d4419958..d5add64039 100644 --- a/management-entity/management-entity-server/src/main/java/org/terracotta/management/entity/server/ManagementAgentServerEntity.java +++ b/management-entity/management-entity-server/src/main/java/org/terracotta/management/entity/server/ManagementAgentServerEntity.java @@ -57,6 +57,7 @@ public void connected(ClientDescriptor clientDescriptor) { // when an entity is fetched, we create the root /management/ (ClientDescriptor) getClientIdentifier(consumer, clientDescriptor).ifPresent(clientIdentifier -> { producer.addNode(array("management", "clients"), clientIdentifier.getClientId(), clientDescriptor); + producer.addNode(array("management", "clients", clientIdentifier.getClientId()), "registry", null); }); } diff --git a/management-entity/management-entity-tests/src/test/java/org/terracotta/management/entity/ManagementAgentServiceTest.java b/management-entity/management-entity-tests/src/test/java/org/terracotta/management/entity/ManagementAgentServiceTest.java index 2bd20f146f..d05268074e 100644 --- a/management-entity/management-entity-tests/src/test/java/org/terracotta/management/entity/ManagementAgentServiceTest.java +++ b/management-entity/management-entity-tests/src/test/java/org/terracotta/management/entity/ManagementAgentServiceTest.java @@ -116,13 +116,13 @@ public ContextContainer getContextContainer() { names = consumer.getChildNamesForNode(new String[]{"management", "clients", clientIdentifier.getClientId()}).get(); assertEquals(2, names.size()); assertThat(names, hasItem("tags")); - assertThat(names, hasItem("cacheManagerName:my-cm-name")); + assertThat(names, hasItem("registry")); assertArrayEquals( new String[]{"EhcachePounder", "webapp-1", "app-server-node-1"}, consumer.getValueForNode(new String[]{"management", "clients", clientIdentifier.getClientId()}, "tags", String[].class).get()); - Map children = consumer.getChildValuesForNode(new String[]{"management", "clients", clientIdentifier.getClientId()}, "cacheManagerName:my-cm-name").get(); + Map children = consumer.getChildValuesForNode(new String[]{"management", "clients", clientIdentifier.getClientId()}, "registry").get(); assertEquals(2, children.size()); assertArrayEquals(registry.getCapabilities().toArray(new Capability[0]), (Capability[]) children.get("capabilities")); assertEquals(registry.getContextContainer(), children.get("contextContainer")); diff --git a/samples/hello-world-entity/src/test/java/org/terracotta/management/entity/helloworld/HelloWorldTest.java b/samples/hello-world-entity/src/test/java/org/terracotta/management/entity/helloworld/HelloWorldTest.java index 75522338a0..0d3608f6ca 100644 --- a/samples/hello-world-entity/src/test/java/org/terracotta/management/entity/helloworld/HelloWorldTest.java +++ b/samples/hello-world-entity/src/test/java/org/terracotta/management/entity/helloworld/HelloWorldTest.java @@ -120,8 +120,8 @@ public void test_hello_world_management() throws Exception { MonitoringConsumerEntity consumerEntity = entityFactory.retrieveOrCreate(getClass().getSimpleName()); String clientIdentifier = consumerEntity.getChildNamesForNode("management", "clients").iterator().next(); - ContextContainer contextContainer = (ContextContainer) consumerEntity.getValueForNode("management", "clients", clientIdentifier, "entityName:my-hello-world-entity-name", "contextContainer"); - Capability[] capabilities = (Capability[]) consumerEntity.getValueForNode("management", "clients", clientIdentifier, "entityName:my-hello-world-entity-name", "capabilities"); + ContextContainer contextContainer = (ContextContainer) consumerEntity.getValueForNode("management", "clients", clientIdentifier, "registry", "contextContainer"); + Capability[] capabilities = (Capability[]) consumerEntity.getValueForNode("management", "clients", clientIdentifier, "registry", "capabilities"); assertEquals(managementRegistry.getContextContainer(), contextContainer); assertEquals(managementRegistry.getCapabilities(), Arrays.asList(capabilities));