| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license |
| * agreements. See the NOTICE file distributed with this work for additional information regarding |
| * copyright ownership. The ASF licenses this file to You 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.apache.geode.internal.admin.remote; |
| |
| import java.io.DataInput; |
| import java.io.DataOutput; |
| import java.io.IOException; |
| import java.io.Serializable; |
| import java.util.Set; |
| import java.util.function.Supplier; |
| |
| import org.apache.geode.DataSerializable; |
| import org.apache.geode.DataSerializer; |
| import org.apache.geode.cache.ClientSession; |
| import org.apache.geode.cache.InterestRegistrationListener; |
| import org.apache.geode.cache.server.ClientSubscriptionConfig; |
| import org.apache.geode.cache.server.ServerLoad; |
| import org.apache.geode.cache.server.ServerLoadProbe; |
| import org.apache.geode.cache.server.ServerLoadProbeAdapter; |
| import org.apache.geode.cache.server.ServerMetrics; |
| import org.apache.geode.distributed.DistributedMember; |
| import org.apache.geode.internal.admin.AdminBridgeServer; |
| import org.apache.geode.internal.cache.AbstractCacheServer; |
| import org.apache.geode.internal.cache.CacheServerImpl; |
| import org.apache.geode.internal.cache.InternalCache; |
| import org.apache.geode.internal.cache.tier.Acceptor; |
| import org.apache.geode.internal.cache.tier.OverflowAttributes; |
| import org.apache.geode.internal.cache.tier.sockets.CacheClientNotifier; |
| import org.apache.geode.internal.cache.tier.sockets.ClientHealthMonitor; |
| import org.apache.geode.internal.cache.tier.sockets.ConnectionListener; |
| import org.apache.geode.internal.cache.tier.sockets.ServerConnectionFactory; |
| import org.apache.geode.internal.net.SocketCreator; |
| import org.apache.geode.internal.security.SecurityService; |
| import org.apache.geode.internal.statistics.StatisticsClock; |
| |
| /** |
| * A remote (serializable) implementation of <code>BridgeServer</code> that is passed between |
| * administration VMs and VMs that host caches with cache servers. |
| * |
| * @since GemFire 4.0 |
| */ |
| public class RemoteBridgeServer extends AbstractCacheServer |
| implements AdminBridgeServer, DataSerializable { |
| |
| private static final long serialVersionUID = 8417391824652384959L; |
| |
| /** Is this cache server running? */ |
| private boolean isRunning; |
| |
| /** The id of this cache server */ |
| private int id; |
| |
| |
| // /** |
| // * The name of the directory in which to store overflowed files for client ha |
| // * queue |
| // */ |
| // private String overflowDirectory=null; |
| ////////////////////// Constructors ////////////////////// |
| |
| /** |
| * A "copy constructor" that creates a <code>RemoteBridgeServer</code> from the contents of the |
| * given <code>BridgeServerImpl</code>. |
| */ |
| RemoteBridgeServer(CacheServerImpl impl) { |
| super(null); |
| this.port = impl.getPort(); |
| this.bindAddress = impl.getBindAddress(); |
| this.hostnameForClients = impl.getHostnameForClients(); |
| if (CacheServerImpl.ENABLE_NOTIFY_BY_SUBSCRIPTION_FALSE) { |
| this.notifyBySubscription = impl.getNotifyBySubscription(); |
| } |
| this.socketBufferSize = impl.getSocketBufferSize(); |
| this.maximumTimeBetweenPings = impl.getMaximumTimeBetweenPings(); |
| this.isRunning = impl.isRunning(); |
| this.maxConnections = impl.getMaxConnections(); |
| this.maxThreads = impl.getMaxThreads(); |
| this.id = System.identityHashCode(impl); |
| this.maximumMessageCount = impl.getMaximumMessageCount(); |
| this.messageTimeToLive = impl.getMessageTimeToLive(); |
| this.groups = impl.getGroups(); |
| this.loadProbe = getProbe(impl.getLoadProbe()); |
| this.loadPollInterval = impl.getLoadPollInterval(); |
| this.tcpNoDelay = impl.getTcpNoDelay(); |
| // added for configuration of ha overflow |
| ClientSubscriptionConfig cscimpl = impl.getClientSubscriptionConfig(); |
| this.clientSubscriptionConfig.setEvictionPolicy(cscimpl.getEvictionPolicy()); |
| this.clientSubscriptionConfig.setCapacity(cscimpl.getCapacity()); |
| String diskStoreName = cscimpl.getDiskStoreName(); |
| if (diskStoreName != null) { |
| this.clientSubscriptionConfig.setDiskStoreName(diskStoreName); |
| } else { |
| this.clientSubscriptionConfig.setOverflowDirectory(cscimpl.getOverflowDirectory()); |
| } |
| } |
| |
| private ServerLoadProbe getProbe(ServerLoadProbe probe) { |
| if (probe == null) { |
| return new RemoteLoadProbe(""); |
| } |
| if (probe instanceof Serializable) { |
| return probe; |
| } else { |
| return new RemoteLoadProbe(probe.toString()); |
| } |
| } |
| |
| /** |
| * Constructor for de-serialization |
| */ |
| public RemoteBridgeServer() { |
| super(null); |
| } |
| |
| //////////////////// Instance Methods //////////////////// |
| |
| @Override |
| public void start() throws IOException { |
| throw new UnsupportedOperationException( |
| "A remote BridgeServer cannot be started."); |
| } |
| |
| @Override |
| public boolean isRunning() { |
| return this.isRunning; |
| } |
| |
| @Override |
| public void stop() { |
| throw new UnsupportedOperationException( |
| "A remote BridgeServer cannot be stopped."); |
| } |
| |
| /** |
| * Returns the cache that is served by this cache server or <code>null</code> if this server is |
| * not running. |
| */ |
| @Override |
| public InternalCache getCache() { |
| throw new UnsupportedOperationException( |
| "Cannot get the Cache of a remote BridgeServer."); |
| } |
| |
| @Override |
| public ConnectionListener getConnectionListener() { |
| throw new UnsupportedOperationException("Unsupported in RemoteBridgeServer"); |
| } |
| |
| @Override |
| public ServerConnectionFactory getServerConnectionFactory() { |
| throw new UnsupportedOperationException("Unsupported in RemoteBridgeServer"); |
| } |
| |
| @Override |
| public long getTimeLimitMillis() { |
| throw new UnsupportedOperationException("Unsupported in RemoteBridgeServer"); |
| } |
| |
| @Override |
| public SecurityService getSecurityService() { |
| throw new UnsupportedOperationException("Unsupported in RemoteBridgeServer"); |
| } |
| |
| @Override |
| public Supplier<SocketCreator> getSocketCreatorSupplier() { |
| throw new UnsupportedOperationException("Unsupported in RemoteBridgeServer"); |
| } |
| |
| @Override |
| public CacheClientNotifier.CacheClientNotifierProvider getCacheClientNotifierProvider() { |
| throw new UnsupportedOperationException("Unsupported in RemoteBridgeServer"); |
| } |
| |
| @Override |
| public ClientHealthMonitor.ClientHealthMonitorProvider getClientHealthMonitorProvider() { |
| throw new UnsupportedOperationException("Unsupported in RemoteBridgeServer"); |
| } |
| |
| @Override |
| public String[] getCombinedGroups() { |
| throw new UnsupportedOperationException("Unsupported in RemoteBridgeServer"); |
| } |
| |
| @Override |
| public StatisticsClock getStatisticsClock() { |
| throw new UnsupportedOperationException("Unsupported in RemoteBridgeServer"); |
| } |
| |
| @Override |
| public ClientSession getClientSession(String durableClientId) { |
| String s = "Cannot get a client session for a remote BridgeServer"; |
| throw new UnsupportedOperationException(s); |
| } |
| |
| @Override |
| public ClientSession getClientSession(DistributedMember member) { |
| String s = "Cannot get a client session for a remote BridgeServer"; |
| throw new UnsupportedOperationException(s); |
| } |
| |
| @Override |
| public Set getAllClientSessions() { |
| String s = |
| "Cannot get all client sessions for a remote BridgeServer"; |
| throw new UnsupportedOperationException(s); |
| } |
| |
| @Override |
| public ClientSubscriptionConfig getClientSubscriptionConfig() { |
| return this.clientSubscriptionConfig; |
| } |
| |
| @Override |
| public int getId() { |
| return this.id; |
| } |
| |
| @Override |
| public void toData(DataOutput out) throws IOException { |
| out.writeInt(this.port); |
| out.writeBoolean(this.notifyBySubscription); |
| out.writeBoolean(this.isRunning); |
| out.writeInt(this.maxConnections); |
| out.writeInt(this.id); |
| out.writeInt(this.maximumTimeBetweenPings); |
| out.writeInt(this.maximumMessageCount); |
| out.writeInt(this.messageTimeToLive); |
| out.writeInt(this.maxThreads); |
| DataSerializer.writeString(this.bindAddress, out); |
| DataSerializer.writeStringArray(this.groups, out); |
| DataSerializer.writeString(this.hostnameForClients, out); |
| DataSerializer.writeObject(this.loadProbe, out); |
| DataSerializer.writePrimitiveLong(this.loadPollInterval, out); |
| out.writeInt(this.socketBufferSize); |
| out.writeBoolean(this.tcpNoDelay); |
| out.writeInt(this.getClientSubscriptionConfig().getCapacity()); |
| DataSerializer.writeString(this.getClientSubscriptionConfig().getEvictionPolicy(), out); |
| DataSerializer.writeString(this.getClientSubscriptionConfig().getDiskStoreName(), out); |
| if (this.getClientSubscriptionConfig().getDiskStoreName() == null) { |
| DataSerializer.writeString(this.getClientSubscriptionConfig().getOverflowDirectory(), out); |
| } |
| } |
| |
| @Override |
| public void fromData(DataInput in) throws IOException, ClassNotFoundException { |
| |
| this.port = in.readInt(); |
| this.notifyBySubscription = in.readBoolean(); |
| this.isRunning = in.readBoolean(); |
| this.maxConnections = in.readInt(); |
| this.id = in.readInt(); |
| this.maximumTimeBetweenPings = in.readInt(); |
| this.maximumMessageCount = in.readInt(); |
| this.messageTimeToLive = in.readInt(); |
| this.maxThreads = in.readInt(); |
| setBindAddress(DataSerializer.readString(in)); |
| setGroups(DataSerializer.readStringArray(in)); |
| setHostnameForClients(DataSerializer.readString(in)); |
| setLoadProbe((ServerLoadProbe) DataSerializer.readObject(in)); |
| setLoadPollInterval(DataSerializer.readPrimitiveLong(in)); |
| this.socketBufferSize = in.readInt(); |
| this.tcpNoDelay = in.readBoolean(); |
| this.getClientSubscriptionConfig().setCapacity(in.readInt()); |
| this.getClientSubscriptionConfig().setEvictionPolicy(DataSerializer.readString(in)); |
| String diskStoreName = DataSerializer.readString(in); |
| if (diskStoreName != null) { |
| this.getClientSubscriptionConfig().setDiskStoreName(diskStoreName); |
| } else { |
| this.getClientSubscriptionConfig().setOverflowDirectory(DataSerializer.readString(in)); |
| } |
| } |
| |
| @Override |
| public Acceptor getAcceptor() { |
| throw new UnsupportedOperationException("not implemented on " + getClass().getSimpleName()); |
| } |
| |
| @Override |
| public Acceptor createAcceptor(OverflowAttributes overflowAttributes) throws IOException { |
| throw new UnsupportedOperationException("not implemented on " + getClass().getSimpleName()); |
| } |
| |
| @Override |
| public String getExternalAddress() { |
| throw new UnsupportedOperationException("not implemented on " + getClass().getSimpleName()); |
| } |
| |
| private static class RemoteLoadProbe extends ServerLoadProbeAdapter { |
| /** The description of this callback */ |
| private final String desc; |
| |
| public RemoteLoadProbe(String desc) { |
| this.desc = desc; |
| } |
| |
| @Override |
| public ServerLoad getLoad(ServerMetrics metrics) { |
| return null; |
| } |
| |
| @Override |
| public String toString() { |
| return desc; |
| } |
| } |
| |
| /** |
| * Registers a new <code>InterestRegistrationListener</code> with the set of |
| * <code>InterestRegistrationListener</code>s. |
| * |
| * @param listener The <code>InterestRegistrationListener</code> to register |
| * |
| * @since GemFire 5.8Beta |
| */ |
| @Override |
| public void registerInterestRegistrationListener(InterestRegistrationListener listener) { |
| final String s = |
| "InterestRegistrationListeners cannot be registered on a remote BridgeServer"; |
| throw new UnsupportedOperationException(s); |
| } |
| |
| /** |
| * Unregisters an existing <code>InterestRegistrationListener</code> from the set of |
| * <code>InterestRegistrationListener</code>s. |
| * |
| * @param listener The <code>InterestRegistrationListener</code> to unregister |
| * |
| * @since GemFire 5.8Beta |
| */ |
| @Override |
| public void unregisterInterestRegistrationListener(InterestRegistrationListener listener) { |
| final String s = |
| "InterestRegistrationListeners cannot be unregistered from a remote BridgeServer"; |
| throw new UnsupportedOperationException(s); |
| } |
| |
| /** |
| * Returns a read-only set of <code>InterestRegistrationListener</code>s registered with this |
| * notifier. |
| * |
| * @return a read-only set of <code>InterestRegistrationListener</code>s registered with this |
| * notifier |
| * |
| * @since GemFire 5.8Beta |
| */ |
| @Override |
| public Set getInterestRegistrationListeners() { |
| final String s = |
| "InterestRegistrationListeners cannot be retrieved from a remote BridgeServer"; |
| throw new UnsupportedOperationException(s); |
| } |
| } |