org.jumpmind.symmetric.service.impl.ConfigurationService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of symmetric-ds Show documentation
Show all versions of symmetric-ds Show documentation
SymmetricDS is an open source database synchronization solution. It is platform-independent,
web-enabled, and database-agnostic. SymmetricDS was first built to replicate changes between 'retail store'
databases and ad centralized 'corporate' database.
The newest version!
/*
* Licensed to JumpMind Inc under one or more contributor
* license agreements. See the NOTICE file distributed
* with this work for additional information regarding
* copyright ownership. JumpMind Inc licenses this file
* to you under the GNU Lesser General Public License (the
* "License"); you may not use this file except in compliance
* with the License.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see
* .
*
* 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.jumpmind.symmetric.service.impl;
import java.io.File;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.jumpmind.symmetric.common.ParameterConstants;
import org.jumpmind.symmetric.db.SqlScript;
import org.jumpmind.symmetric.ddl.Platform;
import org.jumpmind.symmetric.ddl.io.DatabaseIO;
import org.jumpmind.symmetric.ddl.model.Database;
import org.jumpmind.symmetric.model.Channel;
import org.jumpmind.symmetric.model.ChannelMap;
import org.jumpmind.symmetric.model.Node;
import org.jumpmind.symmetric.model.NodeChannel;
import org.jumpmind.symmetric.model.NodeGroupChannelWindow;
import org.jumpmind.symmetric.model.NodeGroupLink;
import org.jumpmind.symmetric.model.NodeGroupLinkAction;
import org.jumpmind.symmetric.model.NodeSecurity;
import org.jumpmind.symmetric.service.IConfigurationService;
import org.jumpmind.symmetric.service.INodeService;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
/**
* Responsible for configuration activities.
*/
public class ConfigurationService extends AbstractService implements IConfigurationService {
private INodeService nodeService;
private Map> nodeChannelCache;
private long nodeChannelCacheTime;
private List defaultChannels;
public ConfigurationService() {
}
public List getGroupLinks() {
return jdbcTemplate.query(getSql("groupsLinksSql"), new NodeGroupLinkMapper());
}
public List getGroupLinksFor(String sourceNodeGroupId) {
return jdbcTemplate.query(getSql("groupsLinksForSql"), new Object[] { sourceNodeGroupId },
new NodeGroupLinkMapper());
}
public List getGroupLinksFor(String sourceNodeGroupId, String targetNodeGroupId) {
List links = getGroupLinksFor(sourceNodeGroupId);
Iterator it = links.iterator();
while (it.hasNext()) {
NodeGroupLink nodeGroupLink = (NodeGroupLink) it.next();
if (!nodeGroupLink.getTargetNodeGroupId().equals(targetNodeGroupId)) {
it.remove();
}
}
return links;
}
public void saveChannel(Channel channel, boolean reloadChannels) {
if (0 == jdbcTemplate.update(getSql("updateChannelSql"), new Object[] {
channel.getProcessingOrder(), channel.getMaxBatchSize(),
channel.getMaxBatchToSend(), channel.getMaxDataToRoute(),
channel.isUseOldDataToRoute() ? 1 : 0, channel.isUseRowDataToRoute() ? 1 : 0,
channel.isUsePkDataToRoute() ? 1 : 0,
channel.isContainsBigLob() ? 1 : 0,
channel.isEnabled() ? 1 : 0, channel.getBatchAlgorithm(),
channel.getExtractPeriodMillis(), channel.getChannelId() })) {
jdbcTemplate.update(getSql("insertChannelSql"), new Object[] { channel.getChannelId(),
channel.getProcessingOrder(), channel.getMaxBatchSize(),
channel.getMaxBatchToSend(), channel.getMaxDataToRoute(),
channel.isUseOldDataToRoute() ? 1 : 0, channel.isUseRowDataToRoute() ? 1 : 0,
channel.isUsePkDataToRoute() ? 1 : 0,
channel.isContainsBigLob() ? 1 : 0,
channel.isEnabled() ? 1 : 0, channel.getBatchAlgorithm(),
channel.getExtractPeriodMillis() });
}
if (reloadChannels) {
reloadChannels();
}
}
public void saveChannel(NodeChannel nodeChannel, boolean reloadChannels) {
saveChannel(nodeChannel.getChannel(), reloadChannels);
}
public void saveNodeChannel(NodeChannel nodeChannel, boolean reloadChannels) {
saveChannel(nodeChannel.getChannel(), false);
saveNodeChannelControl(nodeChannel, reloadChannels);
}
public void saveNodeChannelControl(NodeChannel nodeChannel, boolean reloadChannels) {
if (0 == jdbcTemplate.update(getSql("updateNodeChannelControlSql"), new Object[] {
nodeChannel.isSuspendEnabled() ? 1 : 0, nodeChannel.isIgnoreEnabled() ? 1 : 0,
nodeChannel.getLastExtractedTime(), nodeChannel.getNodeId(),
nodeChannel.getChannelId() })) {
jdbcTemplate.update(getSql("insertNodeChannelControlSql"), new Object[] {
nodeChannel.getNodeId(), nodeChannel.getChannelId(),
nodeChannel.isSuspendEnabled() ? 1 : 0, nodeChannel.isIgnoreEnabled() ? 1 : 0,
nodeChannel.getLastExtractedTime() });
}
if (reloadChannels) {
reloadChannels();
}
}
public void deleteChannel(Channel channel) {
jdbcTemplate.update(getSql("deleteChannelSql"), new Object[] { channel.getChannelId() });
}
public NodeChannel getNodeChannel(String channelId, boolean refreshExtractMillis) {
return getNodeChannel(channelId, nodeService.findIdentityNodeId(), refreshExtractMillis);
}
public NodeChannel getNodeChannel(String channelId, String nodeId, boolean refreshExtractMillis) {
List channels = getNodeChannels(nodeId, refreshExtractMillis);
for (NodeChannel nodeChannel : channels) {
if (nodeChannel.getChannelId().equals(channelId)) {
return nodeChannel;
}
}
return null;
}
public List getNodeChannels(boolean refreshExtractMillis) {
return getNodeChannels(nodeService.findIdentityNodeId(), refreshExtractMillis);
}
public List getNodeChannels(final String nodeId, boolean refreshExtractMillis) {
boolean loaded = false;
long channelCacheTimeoutInMs = parameterService
.getLong(ParameterConstants.CACHE_TIMEOUT_CHANNEL_IN_MS);
List nodeChannels = nodeChannelCache != null ? nodeChannelCache.get(nodeId) : null;
if (System.currentTimeMillis() - nodeChannelCacheTime >= channelCacheTimeoutInMs
|| nodeChannels == null) {
synchronized (this) {
if (System.currentTimeMillis() - nodeChannelCacheTime >= channelCacheTimeoutInMs
|| nodeChannelCache == null || nodeChannelCache.get(nodeId) == null || nodeChannels == null) {
if (System.currentTimeMillis() - nodeChannelCacheTime >= channelCacheTimeoutInMs
|| nodeChannelCache == null) {
nodeChannelCache = new HashMap>();
nodeChannelCacheTime = System.currentTimeMillis();
}
nodeChannels = jdbcTemplate.query(getSql("selectChannelsSql"),
new Object[] { nodeId }, new RowMapper() {
public NodeChannel mapRow(java.sql.ResultSet rs, int arg1)
throws SQLException {
NodeChannel nodeChannel = new NodeChannel();
nodeChannel.setChannelId(rs.getString(1));
nodeChannel.setNodeId(nodeId);
// note that 2 is intentionally missing here.
nodeChannel.setIgnoreEnabled(isSet(rs.getObject(3)));
nodeChannel.setSuspendEnabled(isSet(rs.getObject(4)));
nodeChannel.setProcessingOrder(rs.getInt(5));
nodeChannel.setMaxBatchSize(rs.getInt(6));
nodeChannel.setEnabled(rs.getBoolean(7));
nodeChannel.setMaxBatchToSend(rs.getInt(8));
nodeChannel.setMaxDataToRoute(rs.getInt(9));
nodeChannel.setUseOldDataToRoute(rs.getBoolean(10));
nodeChannel.setUseRowDataToRoute(rs.getBoolean(11));
nodeChannel.setUsePkDataToRoute(rs.getBoolean(12));
nodeChannel.setContainsBigLobs(rs.getBoolean(13));
nodeChannel.setBatchAlgorithm(rs.getString(14));
nodeChannel.setLastExtractedTime(rs.getTimestamp(15));
nodeChannel.setExtractPeriodMillis(rs.getLong(16));
return nodeChannel;
};
});
nodeChannelCache.put(nodeId, nodeChannels);
loaded = true;
}
}
}
if (!loaded && refreshExtractMillis) {
// need to read last extracted time from database regardless of
// whether we used the cache or not.
// locate the nodes in the cache, and update it.
final Map nodeChannelsMap = new HashMap();
for (NodeChannel nc : nodeChannels) {
nodeChannelsMap.put(nc.getChannelId(), nc);
}
jdbcTemplate.query(getSql("selectNodeChannelControlLastExtractTimeSql"),
new Object[] { nodeId }, new ResultSetExtractor