/*
 * Copyright 1999-2020 Alibaba Group Holding Ltd.
 *
 * 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 com.alibaba.nacos.client.config.impl;

import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.auth.spi.RequestResource;
import com.alibaba.nacos.client.config.filter.impl.ConfigResponse;
import com.alibaba.nacos.client.security.SecurityProxy;
import com.alibaba.nacos.client.utils.ParamUtil;
import com.alibaba.nacos.common.utils.ConvertUtils;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.alibaba.nacos.common.utils.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * config transport client,include basic operations of config module.
 *
 * @author liuzunfei
 * @version $Id: ConfigTransportClient.java, v 0.1 2020年08月24日 2:01 PM liuzunfei Exp $
 */
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class ConfigTransportClient {
    
    private static final String CONFIG_INFO_HEADER = "exConfigInfo";
    
    private static final String DEFAULT_CONFIG_INFO = "true";
    
    String encode;
    
    String tenant;
    
    ScheduledExecutorService executor;
    
    final ServerListManager serverListManager;
    
    final Properties properties;
    
    private int maxRetry = 3;
    
    private final long securityInfoRefreshIntervalMills = TimeUnit.SECONDS.toMillis(5);
    
    protected SecurityProxy securityProxy;
    
    public void shutdown() throws NacosException {
        securityProxy.shutdown();
    }
    
    public ConfigTransportClient(Properties properties, ServerListManager serverListManager) {
        
        String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
        if (StringUtils.isBlank(encodeTmp)) {
            this.encode = Constants.ENCODE;
        } else {
            this.encode = encodeTmp.trim();
        }
        
        this.tenant = properties.getProperty(PropertyKeyConst.NAMESPACE);
        this.serverListManager = serverListManager;
        this.properties = properties;
        this.securityProxy = new SecurityProxy(serverListManager.getServerUrls(),
                ConfigHttpClientManager.getInstance().getNacosRestTemplate());
    }
    
    /**
     * Build the resource for current request.
     *
     * @param tenant tenant of config
     * @param group  group of config
     * @param dataId dataId of config
     * @return resource
     */
    protected RequestResource buildResource(String tenant, String group, String dataId) {
        return RequestResource.configBuilder().setNamespace(tenant).setGroup(group).setResource(dataId).build();
    }
    
    protected Map<String, String> getSecurityHeaders(RequestResource resource) throws Exception {
        return securityProxy.getIdentityContext(resource);
    }
    
    /**
     * get common header.
     *
     * @return headers.
     */
    protected Map<String, String> getCommonHeader() {
        Map<String, String> headers = new HashMap<String, String>(16);
        
        String ts = String.valueOf(System.currentTimeMillis());
        String token = MD5Utils.md5Hex(ts + ParamUtil.getAppKey(), Constants.ENCODE);
        
        headers.put(Constants.CLIENT_APPNAME_HEADER, ParamUtil.getAppName());
        headers.put(Constants.CLIENT_REQUEST_TS_HEADER, ts);
        headers.put(Constants.CLIENT_REQUEST_TOKEN_HEADER, token);
        headers.put(CONFIG_INFO_HEADER, DEFAULT_CONFIG_INFO);
        headers.put(Constants.CHARSET_KEY, encode);
        return headers;
    }
    
    private void initMaxRetry(Properties properties) {
        maxRetry = ConvertUtils.toInt(String.valueOf(properties.get(PropertyKeyConst.MAX_RETRY)), Constants.MAX_RETRY);
    }
    
    public void setExecutor(ScheduledExecutorService executor) {
        this.executor = executor;
    }
    
    /**
     * base start client.
     */
    public void start() throws NacosException {
        
        if (StringUtils.isNotBlank(this.properties.getProperty(PropertyKeyConst.USERNAME))) {
            securityProxy.login(this.properties);
            
            this.executor.scheduleWithFixedDelay(new Runnable() {
                @Override
                public void run() {
                    securityProxy.login(properties);
                }
            }, 0, this.securityInfoRefreshIntervalMills, TimeUnit.MILLISECONDS);
            
        }
        
        startInternal();
    }
    
    /**
     * start client inner.
     *
     * @throws NacosException exception may throw.
     */
    public abstract void startInternal() throws NacosException;
    
    /**
     * get client name.
     *
     * @return name.
     */
    public abstract String getName();
    
    /**
     * get encode.
     *
     * @return encode.
     */
    public String getEncode() {
        return this.encode;
    }
    
    /**
     * get tenant.
     *
     * @return tenant.
     */
    public String getTenant() {
        return this.tenant;
    }
    
    /**
     * notify listen config.
     **/
    public abstract void notifyListenConfig();
    
    /**
     * listen change .
     */
    public abstract void executeConfigListen();
    
    /**
     * remove cache implements.
     *
     * @param dataId dataId.
     * @param group  group
     */
    public abstract void removeCache(String dataId, String group);
    
    /**
     * query config.
     *
     * @param dataId      dataId.
     * @param group       group.
     * @param tenat       tenat.
     * @param readTimeous readTimeous.
     * @param notify      query for notify sync.
     * @return content.
     * @throws NacosException throw where query fail .
     */
    public abstract ConfigResponse queryConfig(String dataId, String group, String tenat, long readTimeous,
            boolean notify) throws NacosException;
    
    /**
     * publish config.
     *
     * @param dataId           dataId.
     * @param group            group.
     * @param tenant           tenant.
     * @param appName          appName.
     * @param tag              tag.
     * @param betaIps          betaIps.
     * @param content          content.
     * @param encryptedDataKey encryptedDataKey
     * @param casMd5           casMd5.
     * @param type             type.
     * @return success or not.
     * @throws NacosException throw where publish fail.
     */
    public abstract boolean publishConfig(String dataId, String group, String tenant, String appName, String tag,
            String betaIps, String content, String encryptedDataKey, String casMd5, String type) throws NacosException;
    
    /**
     * remove config.
     *
     * @param dataid dataid.
     * @param group  group.
     * @param tenat  tenat.
     * @param tag    tag.
     * @return success or not.
     * @throws NacosException throw where publish fail.
     */
    public abstract boolean removeConfig(String dataid, String group, String tenat, String tag) throws NacosException;
    
}

@@ -4659,115 +4659,8 @@
     
-%0A        if (StringUtils.isNotBlank(this.properties.getProperty(PropertyKeyConst.USERNAME))) %7B%0A            
 secu
@@ -4693,33 +4693,16 @@
 rties);%0A
-            %0A    
         
@@ -4742,106 +4742,13 @@
 lay(
-new Runnable() %7B%0A                @Override%0A                public void run() %7B%0A                   
+() -%3E
  sec
@@ -4767,33 +4767,36 @@
 ogin(properties)
-;
+, 0,
 %0A               
@@ -4799,28 +4799,8 @@
     
- %7D%0A            %7D, 0,
  thi
@@ -4863,40 +4863,8 @@
 S);%0A
-            %0A        %7D%0A        %0A
     

Fix ram type plugin not login for config module.