Java tutorial
/* * Copyright (C) 2010-2101 Alibaba Group Holding Limited. * * 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.otter.common.push.datasource.media; import java.sql.SQLException; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.sql.DataSource; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.otter.common.push.datasource.DataSourceHanlder; import com.alibaba.otter.shared.common.model.config.data.DataMediaType; import com.alibaba.otter.shared.common.model.config.data.db.DbMediaSource; import com.google.common.base.Function; import com.google.common.collect.GenericMapMaker; import com.google.common.collect.MapEvictionListener; import com.google.common.collect.MapMaker; /** * media group url jdbc:mysql://groupKey=xxx * * @author jianghang 2013-4-18 ?03:33:28 * @version 4.1.8 */ public class MediaPushDataSourceHandler implements DataSourceHanlder { private static final Logger log = LoggerFactory.getLogger(MediaPushDataSourceHandler.class); private static final Pattern PATTERN = Pattern.compile("jdbc:mysql://groupKey=([^&/]+).*", Pattern.CASE_INSENSITIVE); /** * pipeline?DataSource.<br> * key = pipelineId<br> * value = key(dataMediaSourceId)-value(DataSource)<br> */ private Map<Long, Map<DbMediaSource, DataSource>> dataSources; public MediaPushDataSourceHandler() { // soft GenericMapMaker mapMaker = new MapMaker().softValues(); mapMaker = ((MapMaker) mapMaker) .evictionListener(new MapEvictionListener<Long, Map<DbMediaSource, DataSource>>() { public void onEviction(Long pipelineId, Map<DbMediaSource, DataSource> dataSources) { if (dataSources == null) { return; } for (DataSource dataSource : dataSources.values()) { try { MediaPushDataSource mediaPushDataSource = (MediaPushDataSource) dataSource; mediaPushDataSource.destory(); } catch (SQLException e) { log.error("ERROR ## close the datasource has an error", e); } } } }); // map dataSources = new MapMaker().makeComputingMap(new Function<Long, Map<DbMediaSource, DataSource>>() { public Map<DbMediaSource, DataSource> apply(Long pipelineId) { // map return new MapMaker().makeComputingMap(new Function<DbMediaSource, DataSource>() { public DataSource apply(DbMediaSource dbMediaSource) { return createDataSource(dbMediaSource.getUrl(), dbMediaSource.getUsername(), dbMediaSource.getPassword(), dbMediaSource.getDriver(), dbMediaSource.getType(), dbMediaSource.getEncode()); } }); } }); } public boolean support(DbMediaSource dbMediaSource) { return isMediaPushDataSource(dbMediaSource.getUrl()); } public boolean support(DataSource dataSource) { if (dataSource == null) { return false; } return dataSource instanceof MediaPushDataSource; } public DataSource create(Long pipelineId, DbMediaSource dbMediaSource) { return dataSources.get(pipelineId).get(dbMediaSource); } protected DataSource createDataSource(String url, String userName, String password, String driverClassName, DataMediaType dataMediaType, String encoding) { MediaInfo media = parseMediaInfo(url); if (media == null) { if (isMediaPushDataSource(url)) { log.error("{} can't parse as an media groupdatasource, please check!", url); } else { log.info("{} is not a media datasource", url); } return null; } String groupKey = media.getGroupKey(); MediaPushDataSource mediaDataSource = new MediaPushDataSource(url, userName, password, driverClassName, dataMediaType, encoding); mediaDataSource.setDbGroupKey(groupKey); mediaDataSource.init(); return mediaDataSource; } @Override public boolean destory(Long pipelineId) { Map<DbMediaSource, DataSource> sources = dataSources.remove(pipelineId); if (sources != null) { for (DataSource dataSource : sources.values()) { try { MediaPushDataSource mediaPushDataSource = (MediaPushDataSource) dataSource; mediaPushDataSource.destory(); } catch (SQLException e) { log.error("ERROR ## close the datasource has an error", e); } } sources.clear(); } return true; } public static boolean isMediaPushDataSource(String url) { return StringUtils.startsWithIgnoreCase(url, "jdbc:") && StringUtils.containsIgnoreCase(url, "groupKey"); } // ? url public static MediaInfo parseMediaInfo(String url) { if (StringUtils.isEmpty(url)) { return null; } Matcher matcher = PATTERN.matcher(url.trim()); if (!matcher.matches()) { return null; } if (matcher.groupCount() < 1) { throw new IllegalArgumentException( url + " is a media push datasource but have no enough info for groupKey."); } return new MediaInfo(matcher.group(1)); } public static class MediaInfo { String groupKey; public MediaInfo(String groupKey) { this.groupKey = groupKey; } public String getGroupKey() { return groupKey; } } }