| /* |
| * 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.cache.tier.sockets; |
| |
| import static java.util.Collections.unmodifiableMap; |
| |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| import java.util.concurrent.ConcurrentMap; |
| |
| import org.apache.geode.InternalGemFireError; |
| import org.apache.geode.annotations.internal.MakeNotStatic; |
| import org.apache.geode.internal.cache.tier.Command; |
| import org.apache.geode.internal.cache.tier.MessageType; |
| import org.apache.geode.internal.cache.tier.sockets.command.AddPdxEnum; |
| import org.apache.geode.internal.cache.tier.sockets.command.AddPdxType; |
| import org.apache.geode.internal.cache.tier.sockets.command.ClearRegion; |
| import org.apache.geode.internal.cache.tier.sockets.command.ClientReady; |
| import org.apache.geode.internal.cache.tier.sockets.command.CloseConnection; |
| import org.apache.geode.internal.cache.tier.sockets.command.CommitCommand; |
| import org.apache.geode.internal.cache.tier.sockets.command.ContainsKey66; |
| import org.apache.geode.internal.cache.tier.sockets.command.CreateRegion; |
| import org.apache.geode.internal.cache.tier.sockets.command.Destroy70; |
| import org.apache.geode.internal.cache.tier.sockets.command.DestroyRegion; |
| import org.apache.geode.internal.cache.tier.sockets.command.ExecuteFunction70; |
| import org.apache.geode.internal.cache.tier.sockets.command.ExecuteRegionFunction66; |
| import org.apache.geode.internal.cache.tier.sockets.command.ExecuteRegionFunctionGeode18; |
| import org.apache.geode.internal.cache.tier.sockets.command.ExecuteRegionFunctionSingleHop; |
| import org.apache.geode.internal.cache.tier.sockets.command.GatewayReceiverCommand; |
| import org.apache.geode.internal.cache.tier.sockets.command.Get70; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetAll70; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetAllWithCallback; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetClientPRMetadataCommand66; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetClientPartitionAttributesCommand66; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetEntry70; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetFunctionAttribute; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetPDXEnumById; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetPDXIdForEnum; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetPDXIdForType; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetPDXTypeById; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetPdxEnums70; |
| import org.apache.geode.internal.cache.tier.sockets.command.GetPdxTypes70; |
| import org.apache.geode.internal.cache.tier.sockets.command.Invalid; |
| import org.apache.geode.internal.cache.tier.sockets.command.Invalidate70; |
| import org.apache.geode.internal.cache.tier.sockets.command.KeySet; |
| import org.apache.geode.internal.cache.tier.sockets.command.MakePrimary; |
| import org.apache.geode.internal.cache.tier.sockets.command.PeriodicAck; |
| import org.apache.geode.internal.cache.tier.sockets.command.Ping; |
| import org.apache.geode.internal.cache.tier.sockets.command.Put70; |
| import org.apache.geode.internal.cache.tier.sockets.command.PutAll80; |
| import org.apache.geode.internal.cache.tier.sockets.command.PutAllWithCallback; |
| import org.apache.geode.internal.cache.tier.sockets.command.PutUserCredentials; |
| import org.apache.geode.internal.cache.tier.sockets.command.Query651; |
| import org.apache.geode.internal.cache.tier.sockets.command.QueryGeode10; |
| import org.apache.geode.internal.cache.tier.sockets.command.QueryWithParametersGeode10; |
| import org.apache.geode.internal.cache.tier.sockets.command.RegisterDataSerializers; |
| import org.apache.geode.internal.cache.tier.sockets.command.RegisterInstantiators; |
| import org.apache.geode.internal.cache.tier.sockets.command.RegisterInterest61; |
| import org.apache.geode.internal.cache.tier.sockets.command.RegisterInterestList66; |
| import org.apache.geode.internal.cache.tier.sockets.command.RemoveAll; |
| import org.apache.geode.internal.cache.tier.sockets.command.RemoveUserAuth; |
| import org.apache.geode.internal.cache.tier.sockets.command.RequestEventValue; |
| import org.apache.geode.internal.cache.tier.sockets.command.RollbackCommand; |
| import org.apache.geode.internal.cache.tier.sockets.command.Size; |
| import org.apache.geode.internal.cache.tier.sockets.command.TXFailoverCommand; |
| import org.apache.geode.internal.cache.tier.sockets.command.TXSynchronizationCommand; |
| import org.apache.geode.internal.cache.tier.sockets.command.UnregisterInterest; |
| import org.apache.geode.internal.cache.tier.sockets.command.UnregisterInterestList; |
| import org.apache.geode.internal.cache.tier.sockets.command.UpdateClientNotification; |
| import org.apache.geode.internal.serialization.KnownVersion; |
| |
| /** |
| * A <code>CommandInitializer</code> maintains version specific commands map. |
| * |
| * @since GemFire 5.7 |
| */ |
| |
| public class CommandInitializer implements CommandRegistry { |
| |
| @Deprecated |
| @MakeNotStatic |
| static final CommandInitializer instance = new CommandInitializer(); |
| |
| /** |
| * Gets legacy singleton instance. |
| * |
| * @deprecated Efforts should be made to get and instance from the cache or other object. |
| * |
| * @return legacy singleton instance. Instance is not immutable. |
| */ |
| @Deprecated |
| public static CommandInitializer getDefaultInstance() { |
| return instance; |
| } |
| |
| final Map<KnownVersion, Map<Integer, Command>> unmodifiableRegisteredCommands; |
| final LinkedHashMap<KnownVersion, ConcurrentMap<Integer, Command>> modifiableRegisteredCommands; |
| |
| public CommandInitializer() { |
| modifiableRegisteredCommands = initializeAllCommands(); |
| unmodifiableRegisteredCommands = makeUnmodifiable(modifiableRegisteredCommands); |
| } |
| |
| @Override |
| public void register(int messageType, |
| Map<KnownVersion, Command> versionToNewCommand) { |
| if (!registerCommand(messageType, versionToNewCommand, modifiableRegisteredCommands)) { |
| throw new InternalGemFireError(String.format("Message %d was not registered.", messageType)); |
| } |
| } |
| |
| /** |
| * Gets the command map for a given version. |
| * |
| * @param version of command map to return. |
| * |
| * @return immutable {@link Map} for {@link MessageType} to {@link Command}. |
| */ |
| @Override |
| public Map<Integer, Command> get(final KnownVersion version) { |
| return unmodifiableRegisteredCommands.get(version); |
| } |
| |
| /** |
| * Iterate through all the Geode versions add a command to the map for that version |
| * |
| * @return returns true if command was registered or same command was already registered, |
| * otherwise false. |
| * @throws InternalGemFireError if a different command was already registered. |
| */ |
| boolean registerCommand(final int messageType, |
| final Map<KnownVersion, Command> versionToNewCommand, |
| final LinkedHashMap<KnownVersion, ConcurrentMap<Integer, Command>> allCommands) { |
| boolean modified = false; |
| Command command = null; |
| |
| for (Map.Entry<KnownVersion, ConcurrentMap<Integer, Command>> entry : allCommands.entrySet()) { |
| KnownVersion version = entry.getKey(); |
| |
| // Get the current set of commands for this version. |
| Map<Integer, Command> commandMap = entry.getValue(); |
| |
| // See if we have a new command to insert into this map. Otherwise, keep using the command we |
| // have already read |
| Command newCommand = versionToNewCommand.get(version); |
| if (newCommand != null) { |
| command = newCommand; |
| } |
| if (command != null) { |
| Command oldCommand = commandMap.get(messageType); |
| if (oldCommand != null && oldCommand != command) { |
| throw new InternalGemFireError("Command is already defined int the map for message Type " |
| + MessageType.getString(messageType) + ". Old Value=" + commandMap.get(messageType) |
| + ", newValue=" + command + ", version=" + version); |
| } |
| commandMap.put(messageType, command); |
| modified = true; |
| } |
| } |
| return modified; |
| } |
| |
| private static LinkedHashMap<KnownVersion, ConcurrentMap<Integer, Command>> initializeAllCommands() { |
| final LinkedHashMap<KnownVersion, ConcurrentMap<Integer, Command>> allCommands = |
| new LinkedHashMap<>(); |
| |
| final ConcurrentMap<Integer, Command> gfe81Commands = buildGfe81Commands(); |
| allCommands.put(KnownVersion.GFE_81, gfe81Commands); |
| |
| final ConcurrentMap<Integer, Command> gfe90Commands = |
| buildGfe90Commands(allCommands.get(KnownVersion.GFE_81)); |
| allCommands.put(KnownVersion.GFE_90, gfe90Commands); |
| allCommands.put(KnownVersion.GEODE_1_1_0, gfe90Commands); |
| allCommands.put(KnownVersion.GEODE_1_1_1, gfe90Commands); |
| allCommands.put(KnownVersion.GEODE_1_2_0, gfe90Commands); |
| allCommands.put(KnownVersion.GEODE_1_3_0, gfe90Commands); |
| allCommands.put(KnownVersion.GEODE_1_4_0, gfe90Commands); |
| allCommands.put(KnownVersion.GEODE_1_5_0, gfe90Commands); |
| allCommands.put(KnownVersion.GEODE_1_6_0, gfe90Commands); |
| allCommands.put(KnownVersion.GEODE_1_7_0, gfe90Commands); |
| |
| final ConcurrentMap<Integer, Command> geode18Commands = |
| buildGeode18Commands(allCommands.get(KnownVersion.GEODE_1_7_0)); |
| allCommands.put(KnownVersion.GEODE_1_8_0, geode18Commands); |
| allCommands.put(KnownVersion.GEODE_1_9_0, geode18Commands); |
| allCommands.put(KnownVersion.GEODE_1_10_0, geode18Commands); |
| allCommands.put(KnownVersion.GEODE_1_11_0, geode18Commands); |
| allCommands.put(KnownVersion.GEODE_1_12_0, geode18Commands); |
| allCommands.put(KnownVersion.GEODE_1_12_1, geode18Commands); |
| allCommands.put(KnownVersion.GEODE_1_13_0, geode18Commands); |
| allCommands.put(KnownVersion.GEODE_1_13_1, geode18Commands); |
| |
| allCommands.put(KnownVersion.GEODE_1_14_0, geode18Commands); |
| |
| return allCommands; |
| } |
| |
| private static ConcurrentMap<Integer, Command> buildGeode18Commands( |
| final ConcurrentMap<Integer, Command> baseCommands) { |
| final ConcurrentMap<Integer, Command> commands = new ConcurrentHashMap<>(baseCommands); |
| initializeGeode18Commands(commands); |
| return commands; |
| } |
| |
| private static ConcurrentMap<Integer, Command> buildGfe90Commands( |
| final ConcurrentMap<Integer, Command> baseCommands) { |
| final ConcurrentMap<Integer, Command> commands = new ConcurrentHashMap<>(baseCommands); |
| initializeGfe90Commands(commands); |
| return commands; |
| } |
| |
| private static ConcurrentMap<Integer, Command> buildGfe81Commands() { |
| final ConcurrentMap<Integer, Command> commands = new ConcurrentHashMap<>(); |
| initializeGfe81Commands(commands); |
| return commands; |
| } |
| |
| static void initializeGeode18Commands(final Map<Integer, Command> commands) { |
| commands.put(MessageType.EXECUTE_REGION_FUNCTION, ExecuteRegionFunctionGeode18.getCommand()); |
| } |
| |
| static void initializeGfe90Commands(final Map<Integer, Command> commands) { |
| commands.put(MessageType.QUERY_WITH_PARAMETERS, QueryWithParametersGeode10.getCommand()); |
| commands.put(MessageType.QUERY, QueryGeode10.getCommand()); |
| } |
| |
| static void initializeGfe81Commands(final Map<Integer, Command> commands) { |
| commands.put(MessageType.PING, Ping.getCommand()); |
| commands.put(MessageType.QUERY, |
| org.apache.geode.internal.cache.tier.sockets.command.Query.getCommand()); |
| commands.put(MessageType.CLEAR_REGION, ClearRegion.getCommand()); |
| commands.put(MessageType.DESTROY_REGION, DestroyRegion.getCommand()); |
| commands.put(MessageType.UNREGISTER_INTEREST, UnregisterInterest.getCommand()); |
| commands.put(MessageType.UNREGISTER_INTEREST_LIST, UnregisterInterestList.getCommand()); |
| commands.put(MessageType.KEY_SET, KeySet.getCommand()); |
| commands.put(MessageType.CREATE_REGION, CreateRegion.getCommand()); |
| commands.put(MessageType.MAKE_PRIMARY, MakePrimary.getCommand()); |
| commands.put(MessageType.PERIODIC_ACK, PeriodicAck.getCommand()); |
| commands.put(MessageType.REGISTER_INSTANTIATORS, RegisterInstantiators.getCommand()); |
| commands.put(MessageType.UPDATE_CLIENT_NOTIFICATION, |
| UpdateClientNotification.getCommand()); |
| commands.put(MessageType.CLOSE_CONNECTION, CloseConnection.getCommand()); |
| commands.put(MessageType.CLIENT_READY, ClientReady.getCommand()); |
| commands.put(MessageType.INVALID, Invalid.getCommand()); |
| |
| commands.put(MessageType.REGISTER_INTEREST, RegisterInterest61.getCommand()); |
| commands.put(MessageType.REQUEST_EVENT_VALUE, RequestEventValue.getCommand()); |
| commands.put(MessageType.REGISTER_DATASERIALIZERS, RegisterDataSerializers.getCommand()); |
| |
| commands.put(MessageType.USER_CREDENTIAL_MESSAGE, PutUserCredentials.getCommand()); |
| commands.put(MessageType.REMOVE_USER_AUTH, RemoveUserAuth.getCommand()); |
| commands.put(MessageType.EXECUTE_REGION_FUNCTION_SINGLE_HOP, |
| ExecuteRegionFunctionSingleHop.getCommand()); |
| |
| commands.put(MessageType.QUERY_WITH_PARAMETERS, Query651.getCommand()); |
| |
| commands.put(MessageType.GET_CLIENT_PR_METADATA, GetClientPRMetadataCommand66.getCommand()); |
| |
| commands.put(MessageType.ADD_PDX_TYPE, AddPdxType.getCommand()); |
| commands.put(MessageType.GET_PDX_ID_FOR_TYPE, GetPDXIdForType.getCommand()); |
| commands.put(MessageType.GET_PDX_TYPE_BY_ID, GetPDXTypeById.getCommand()); |
| commands.put(MessageType.SIZE, Size.getCommand()); |
| commands.put(MessageType.COMMIT, CommitCommand.getCommand()); |
| commands.put(MessageType.ROLLBACK, RollbackCommand.getCommand()); |
| commands.put(MessageType.TX_FAILOVER, TXFailoverCommand.getCommand()); |
| commands.put(MessageType.TX_SYNCHRONIZATION, TXSynchronizationCommand.getCommand()); |
| commands.put(MessageType.GET_CLIENT_PARTITION_ATTRIBUTES, |
| GetClientPartitionAttributesCommand66.getCommand()); |
| commands.put(MessageType.REGISTER_INTEREST_LIST, RegisterInterestList66.getCommand()); |
| commands.put(MessageType.GET_FUNCTION_ATTRIBUTES, GetFunctionAttribute.getCommand()); |
| commands.put(MessageType.EXECUTE_REGION_FUNCTION, ExecuteRegionFunction66.getCommand()); |
| commands.put(MessageType.GATEWAY_RECEIVER_COMMAND, GatewayReceiverCommand.getCommand()); |
| commands.put(MessageType.CONTAINS_KEY, ContainsKey66.getCommand()); |
| |
| commands.put(MessageType.ADD_PDX_ENUM, AddPdxEnum.getCommand()); |
| commands.put(MessageType.GET_PDX_ID_FOR_ENUM, GetPDXIdForEnum.getCommand()); |
| commands.put(MessageType.GET_PDX_ENUM_BY_ID, GetPDXEnumById.getCommand()); |
| |
| commands.put(MessageType.REQUEST, Get70.getCommand()); |
| commands.put(MessageType.GET_ENTRY, GetEntry70.getCommand()); |
| commands.put(MessageType.GET_ALL_70, GetAll70.getCommand()); |
| commands.put(MessageType.PUT, Put70.getCommand()); |
| commands.put(MessageType.DESTROY, Destroy70.getCommand()); |
| commands.put(MessageType.INVALIDATE, Invalidate70.getCommand()); |
| commands.put(MessageType.GET_PDX_TYPES, GetPdxTypes70.getCommand()); |
| commands.put(MessageType.GET_PDX_ENUMS, GetPdxEnums70.getCommand()); |
| commands.put(MessageType.EXECUTE_FUNCTION, ExecuteFunction70.getCommand()); |
| |
| commands.put(MessageType.PUTALL, PutAll80.getCommand()); |
| commands.put(MessageType.GET_ALL_WITH_CALLBACK, GetAllWithCallback.getCommand()); |
| commands.put(MessageType.PUT_ALL_WITH_CALLBACK, PutAllWithCallback.getCommand()); |
| commands.put(MessageType.REMOVE_ALL, RemoveAll.getCommand()); |
| } |
| |
| static Map<KnownVersion, Map<Integer, Command>> makeUnmodifiable( |
| final Map<KnownVersion, ConcurrentMap<Integer, Command>> modifiableMap) { |
| final Map<KnownVersion, Map<Integer, Command>> unmodifiableMap = |
| new LinkedHashMap<>(modifiableMap.size()); |
| for (Map.Entry<KnownVersion, ConcurrentMap<Integer, Command>> e : modifiableMap.entrySet()) { |
| unmodifiableMap.put(e.getKey(), unmodifiableMap(e.getValue())); |
| } |
| return unmodifiableMap(unmodifiableMap); |
| } |
| |
| } |