/** * VMware Continuent Tungsten Replicator * Copyright (C) 2015 VMware, Inc. All rights reserved. * * 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. * * Initial developer(s): Teemu Ollakka * Contributor(s): Robert Hodges */ package com.continuent.tungsten.manager.resource.logical; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import com.continuent.tungsten.common.cluster.resource.DataSource; import com.continuent.tungsten.common.cluster.resource.DataSourceRole; import com.continuent.tungsten.common.cluster.resource.ResourceState; import com.continuent.tungsten.common.config.TungstenProperties; import com.continuent.tungsten.common.exception.ResourceException; public class DataService { @SuppressWarnings("unused") private static final long serialVersionUID = 1L; private String dataServiceName = null; private Map<String, DataSource> resources = new TreeMap<String, DataSource>(); private Map<String, ArrayList<DataSource>> resourcesByRole = new HashMap<String, ArrayList<DataSource>>(); public DataService(String dataServiceName, Map<String, TungstenProperties> dataSourceMap) throws ResourceException { this.dataServiceName = dataServiceName; for (TungstenProperties ds : dataSourceMap.values()) { DataSource newDs = new DataSource(ds); newDs.setDataServiceName(this.dataServiceName); resources.put(newDs.getName(), newDs); addByRole(newDs); } } public boolean isActiveMaster(String dsName) { DataSource currentMaster = null; try { currentMaster = getCurrentMaster(); if (currentMaster.getName().equals(dsName)) return true; } catch (ResourceException ignored) { } return false; } public boolean isActiveSlave(String dsName) { DataSource foundDs = null; try { foundDs = getDataSource(dsName); if (foundDs.getRole().equals(DataSourceRole.slave.toString()) && !(foundDs.getState() == ResourceState.FAILED || foundDs .getState() == ResourceState.SHUNNED)) return true; } catch (ResourceException ignored) { } return false; } public DataSource getCurrentMaster() throws ResourceException { ArrayList<DataSource> dsByRole = getRoleArray(DataSourceRole.master .toString()); DataSource foundDs = null; for (DataSource ds : dsByRole) { if (ds.getRole().equals(DataSourceRole.master.toString()) && ds.getState() != ResourceState.SHUNNED && ds.getState() != ResourceState.FAILED) { foundDs = ds; } } if (foundDs == null) { throw new ResourceException("No master is currently available"); } return foundDs; } public void removeDataSource(DataSource dsToRemove) throws ResourceException { DataSource foundDs = resources.get(dsToRemove.getName()); if (foundDs == null) { throw new ResourceException(String.format( "Did not find a datasource named '%s' in service '%s'", dsToRemove.getName(), getDataServiceName())); } resources.remove(dsToRemove.getName()); removeByRole(dsToRemove); } public DataSource getDataSource(String dsName) throws ResourceException { DataSource ds = null; synchronized (resources) { ds = resources.get(dsName); } if (ds == null) { throw new ResourceException(String.format( "Datasource %s not found for service %s", dsName, dataServiceName)); } return ds; } public Map<String, DataSource> getAllDataSources() { synchronized (this) { return resources; } } /** * Returns the dataServiceName value. * * @return Returns the dataServiceName. */ public String getDataServiceName() { return dataServiceName; } /** * Sets the dataServiceName value. * * @param dataServiceName The dataServiceName to set. */ public void setDataServiceName(String dataServiceName) { this.dataServiceName = dataServiceName; } private void addByRole(DataSource ds) throws ResourceException { validate(ds); synchronized (this) { ArrayList<DataSource> dsByRole = getRoleArray(ds.getRole()); dsByRole.add(ds); } } private void removeByRole(DataSource ds) { ArrayList<DataSource> dsByRole = getRoleArray(ds.getRole()); int objIndex = -1; if ((objIndex = dsByRole.indexOf(ds)) >= 0) { dsByRole.remove(objIndex); } } private ArrayList<DataSource> getRoleArray(String role) { ArrayList<DataSource> dsByRole = resourcesByRole.get(role); if (dsByRole == null) { dsByRole = new ArrayList<DataSource>(); resourcesByRole.put(role, dsByRole); } return dsByRole; } private void validate(DataSource ds) throws ResourceException { if ((ds.getName() == null || ds.getName().length() == 0) || (ds.getDriver() == null || ds.getDriver().length() == 0) || (ds.getUrl() == null || ds.getUrl().length() == 0) || ((ds.getRole().equals(DataSourceRole.undefined.toString()) && !ds .isComposite()))) { throw new ResourceException(String.format( "Malformed datasource encountered: %s", ds.toString())); } } }