All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alipay.sofa.tracer.plugins.datasource.SmartDataSource Maven / Gradle / Ivy

/*
 * 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.alipay.sofa.tracer.plugins.datasource;

import com.alipay.common.tracer.core.utils.StringUtils;
import com.alipay.sofa.tracer.plugins.datasource.tracer.ConnectionTraceInterceptor;
import com.alipay.sofa.tracer.plugins.datasource.tracer.DataSourceClientTracer;
import com.alipay.sofa.tracer.plugins.datasource.tracer.DataSourceTracerKeys;
import com.alipay.sofa.tracer.plugins.datasource.tracer.Endpoint;
import com.alipay.sofa.tracer.plugins.datasource.tracer.KeyValueAnnotation;
import com.alipay.sofa.tracer.plugins.datasource.tracer.StatementTracerInterceptor;
import com.alipay.sofa.tracer.plugins.datasource.utils.DataSourceUtils;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author shusong.yss
 * @author qilong.zql
 * @author chenchen
 * @since 2.2.0
 */
public class SmartDataSource extends BaseDataSource {

    private String                           appName;

    private String                           database;

    private String                           dbType;

    private boolean                          isEnableTrace = Boolean.TRUE;

    private DataSourceClientTracer           clientTracer  = DataSourceClientTracer
                                                               .getDataSourceClientTracer();

    /**
     * DataSource basic info. Including appName, dbType, dbName, dbEndpoint.
     */
    protected final List traceAnnotations;

    public SmartDataSource() {
        this(null);
    }

    public SmartDataSource(DataSource delegate) {
        super(delegate);
        traceAnnotations = new ArrayList<>();
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public void setDatabase(String database) {
        this.database = database;
    }

    public void setDbType(String dbType) {
        this.dbType = dbType;
    }

    public boolean isEnableTrace() {
        return isEnableTrace;
    }

    public void setEnableTrace(boolean enableTrace) {
        isEnableTrace = enableTrace;
    }

    public DataSourceClientTracer getClientTracer() {
        return clientTracer;
    }

    public void setClientTracer(DataSourceClientTracer clientTracer) {
        this.clientTracer = clientTracer;
    }

    public List getTraceAnnotations() {
        return traceAnnotations;
    }

    /**
     * init method must be invoked first after construction
     */
    @Override
    public void init() {
        if (initialized.compareAndSet(false, true)) {
            if (StringUtils.isBlank(dbType)) {
                throw new IllegalArgumentException("dbType must not be null or empty");
            }
            String upperDbType = dbType.toUpperCase();
            if (!DBType.supportedDbTypes.containsKey(upperDbType)) {
                throw new IllegalArgumentException("dbType: " + upperDbType
                                                   + "not in support list: "
                                                   + DBType.supportedDbTypes);
            }
            traceAnnotations
                .add(new KeyValueAnnotation(DataSourceTracerKeys.DATABASE_TYPE, dbType));
            if (StringUtils.isBlank(database)) {
                throw new IllegalArgumentException("database must not be null or empty");
            }
            traceAnnotations.add(new KeyValueAnnotation(DataSourceTracerKeys.DATABASE_NAME,
                database));
            if (StringUtils.isBlank(appName)) {
                throw new IllegalArgumentException("appName must not be null or empty");
            }
            traceAnnotations.add(new KeyValueAnnotation(DataSourceTracerKeys.LOCAL_APP, appName));

            DataSource dataSource = getDelegate();
            String jdbcUrl = DataSourceUtils.getJdbcUrl(dataSource);
            //tns or others
            traceAnnotations.add(new KeyValueAnnotation(DataSourceTracerKeys.DATABASE_ENDPOINT,
                getEndpointsStr(DataSourceUtils.getEndpointsFromConnectionURL(jdbcUrl))));

            Prop prop = getProp();
            List interceptors = getInterceptors();
            if (interceptors != null && !interceptors.isEmpty()) {
                prop.addAll(interceptors);
            }
            if (isEnableTrace && clientTracer != null) {
                setupStatementTracerInterceptor();
                setupConnectionTracerInterceptor();
            }
        }
    }

    protected void setupStatementTracerInterceptor() {
        StatementTracerInterceptor statementTracerInterceptor = new StatementTracerInterceptor();
        statementTracerInterceptor.setClientTracer(clientTracer);
        getProp().addInterceptor(statementTracerInterceptor);
    }

    protected void setupConnectionTracerInterceptor() {
        List dataSourceInterceptors = getDataSourceInterceptors();
        ConnectionTraceInterceptor connectionTraceInterceptor = new ConnectionTraceInterceptor(
            traceAnnotations);
        if (dataSourceInterceptors != null) {
            dataSourceInterceptors.add(connectionTraceInterceptor);
        } else {
            setDataSourceInterceptors(Collections
                . singletonList(connectionTraceInterceptor));
        }
    }

    private String getEndpointsStr(List endpoints) {
        if (null == endpoints) {
            return StringUtils.EMPTY_STRING;
        }

        int endpointSize = endpoints.size();
        if (0 == endpointSize) {
            return StringUtils.EMPTY_STRING;
        }

        if (1 == endpointSize) {
            return endpoints.get(0).getEndpoint();
        }

        StringBuilder sb = new StringBuilder();
        for (Endpoint endpoint : endpoints) {
            sb.append(endpoint.getEndpoint()).append("/");
        }
        return sb.substring(0, sb.lastIndexOf("/"));
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy