/** * 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 com.alibaba.rocketmq.broker.subscription; import com.alibaba.rocketmq.broker.BrokerController; import com.alibaba.rocketmq.broker.BrokerPathConfigHelper; import com.alibaba.rocketmq.common.ConfigManager; import com.alibaba.rocketmq.common.DataVersion; import com.alibaba.rocketmq.common.MixAll; import com.alibaba.rocketmq.common.constant.LoggerName; import com.alibaba.rocketmq.common.subscription.SubscriptionGroupConfig; import com.alibaba.rocketmq.remoting.protocol.RemotingSerializable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.util.Iterator; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; /** * @author shijia.wxr */ public class SubscriptionGroupManager extends ConfigManager { private static final Logger log = LoggerFactory.getLogger(LoggerName.BrokerLoggerName); private final ConcurrentHashMap<String, SubscriptionGroupConfig> subscriptionGroupTable = new ConcurrentHashMap<String, SubscriptionGroupConfig>(1024); private final DataVersion dataVersion = new DataVersion(); private transient BrokerController brokerController; public SubscriptionGroupManager() { this.init(); } private void init() { { SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig(); subscriptionGroupConfig.setGroupName(MixAll.TOOLS_CONSUMER_GROUP); this.subscriptionGroupTable.put(MixAll.TOOLS_CONSUMER_GROUP, subscriptionGroupConfig); } { SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig(); subscriptionGroupConfig.setGroupName(MixAll.FILTERSRV_CONSUMER_GROUP); this.subscriptionGroupTable.put(MixAll.FILTERSRV_CONSUMER_GROUP, subscriptionGroupConfig); } { SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig(); subscriptionGroupConfig.setGroupName(MixAll.SELF_TEST_CONSUMER_GROUP); this.subscriptionGroupTable.put(MixAll.SELF_TEST_CONSUMER_GROUP, subscriptionGroupConfig); } { SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig(); subscriptionGroupConfig.setGroupName(MixAll.ONS_HTTP_PROXY_GROUP); subscriptionGroupConfig.setConsumeBroadcastEnable(true); this.subscriptionGroupTable.put(MixAll.ONS_HTTP_PROXY_GROUP, subscriptionGroupConfig); } { SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig(); subscriptionGroupConfig.setGroupName(MixAll.CID_ONSAPI_PULL_GROUP); subscriptionGroupConfig.setConsumeBroadcastEnable(true); this.subscriptionGroupTable.put(MixAll.CID_ONSAPI_PULL_GROUP, subscriptionGroupConfig); } { SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig(); subscriptionGroupConfig.setGroupName(MixAll.CID_ONSAPI_PERMISSION_GROUP); subscriptionGroupConfig.setConsumeBroadcastEnable(true); this.subscriptionGroupTable.put(MixAll.CID_ONSAPI_PERMISSION_GROUP, subscriptionGroupConfig); } { SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig(); subscriptionGroupConfig.setGroupName(MixAll.CID_ONSAPI_OWNER_GROUP); subscriptionGroupConfig.setConsumeBroadcastEnable(true); this.subscriptionGroupTable.put(MixAll.CID_ONSAPI_OWNER_GROUP, subscriptionGroupConfig); } } public SubscriptionGroupManager(BrokerController brokerController) { this.brokerController = brokerController; this.init(); } public void updateSubscriptionGroupConfig(final SubscriptionGroupConfig config) { SubscriptionGroupConfig old = this.subscriptionGroupTable.put(config.getGroupName(), config); if (old != null) { log.info("update subscription group config, old: " + old + " new: " + config); } else { log.info("create new subscription group, " + config); } this.dataVersion.nextVersion(); this.persist(); } public void disableConsume(final String groupName) { SubscriptionGroupConfig old = this.subscriptionGroupTable.get(groupName); if (old != null) { old.setConsumeEnable(false); this.dataVersion.nextVersion(); } } public SubscriptionGroupConfig findSubscriptionGroupConfig(final String group) { SubscriptionGroupConfig subscriptionGroupConfig = this.subscriptionGroupTable.get(group); if (null == subscriptionGroupConfig) { if (brokerController.getBrokerConfig().isAutoCreateSubscriptionGroup() || MixAll.isSysConsumerGroup(group)) { subscriptionGroupConfig = new SubscriptionGroupConfig(); subscriptionGroupConfig.setGroupName(group); SubscriptionGroupConfig preConfig = this.subscriptionGroupTable.putIfAbsent(group, subscriptionGroupConfig); if(null == preConfig){ log.info("auto create a subscription group, {}", subscriptionGroupConfig.toString()); } this.dataVersion.nextVersion(); this.persist(); } } return subscriptionGroupConfig; } @Override public String encode() { return this.encode(false); } @Override public String configFilePath() { //return BrokerPathConfigHelper.getSubscriptionGroupPath(this.brokerController.getMessageStoreConfig().getStorePathRootDir()); return BrokerPathConfigHelper.getSubscriptionGroupPath(System.getProperty("user.home") + File.separator + "store"); } @Override public void decode(String jsonString) { if (jsonString != null) { SubscriptionGroupManager obj = RemotingSerializable.fromJson(jsonString, SubscriptionGroupManager.class); if (obj != null) { this.subscriptionGroupTable.putAll(obj.subscriptionGroupTable); this.dataVersion.assignNewOne(obj.dataVersion); this.printLoadDataWhenFirstBoot(obj); } } } public String encode(final boolean prettyFormat) { return RemotingSerializable.toJson(this, prettyFormat); } private void printLoadDataWhenFirstBoot(final SubscriptionGroupManager sgm) { Iterator<Entry<String, SubscriptionGroupConfig>> it = sgm.getSubscriptionGroupTable().entrySet().iterator(); while (it.hasNext()) { Entry<String, SubscriptionGroupConfig> next = it.next(); log.info("load exist subscription group, {}", next.getValue().toString()); } } public ConcurrentHashMap<String, SubscriptionGroupConfig> getSubscriptionGroupTable() { return subscriptionGroupTable; } public DataVersion getDataVersion() { return dataVersion; } public void deleteSubscriptionGroupConfig(final String groupName) { SubscriptionGroupConfig old = this.subscriptionGroupTable.remove(groupName); if (old != null) { log.info("delete subscription group OK, subscription group: " + old); this.dataVersion.nextVersion(); this.persist(); } else { log.warn("delete subscription group failed, subscription group: " + groupName + " not exist"); } } }