package com.tesora.dve.siteprovider;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import java.util.Comparator;
import java.util.Map;
import com.tesora.dve.worker.WorkerFactory;
import io.netty.channel.EventLoopGroup;
import org.apache.log4j.Logger;
import com.tesora.dve.common.ShowSchema;
import com.tesora.dve.common.catalog.CatalogDAO;
import com.tesora.dve.common.catalog.CatalogEntity;
import com.tesora.dve.common.catalog.PersistentSite;
import com.tesora.dve.common.catalog.StorageSite;
import com.tesora.dve.exceptions.PEException;
import com.tesora.dve.server.statistics.manager.LogSiteStatisticRequest;
import com.tesora.dve.server.statistics.SiteStatKey.SiteType;
import com.tesora.dve.sql.transform.execution.AdhocCatalogEntity;
import com.tesora.dve.sql.util.ListOfPairs;
import com.tesora.dve.worker.AdditionalConnectionInfo;
import com.tesora.dve.worker.UserAuthentication;
import com.tesora.dve.worker.Worker;
public class DynamicSiteInfo extends AbstractDynamicSiteInfo implements StorageSite {
private static Logger logger = Logger.getLogger(DynamicSiteInfo.class);
private long lastQueryTime = System.currentTimeMillis();
static final Comparator<DynamicSiteInfo> LOAD_AND_TIME_ORDER = new Comparator<DynamicSiteInfo>() {
@Override
public int compare(DynamicSiteInfo o1, DynamicSiteInfo o2) {
int diff = o1.currentQueries.get() - o2.currentQueries.get();
return (diff != 0) ? diff : (int) (o1.lastQueryTime - o2.lastQueryTime);
}
};
private UserAuthentication siteAuth;
protected DynamicSiteInfo() {
}
public DynamicSiteInfo(String provider, String pool, String name, String url, String user, String password, int maxQueries) {
super(provider, pool, name, url, user, password, maxQueries);
siteAuth = new UserAuthentication(user, password, false);
}
// ------------------------------------------------------------------------
// The following methods are from the StorageSite interface
@Override
public String getName() {
return getFullName();
}
@Override
public String getMasterUrl() {
return getUrl();
}
@Override
public PersistentSite getRecoverableSite(CatalogDAO c) {
return null;
}
@Override
public Worker pickWorker(Map<StorageSite, Worker> workerMap) throws PEException {
return workerMap.get(this);
}
@Override
public void annotateStatistics(LogSiteStatisticRequest sNotice) {
sNotice.setSiteDetails(getName(), SiteType.DYNAMIC);
}
// ------------------------------------------------------------------------
@Override
public void incrementUsageCount() {
currentQueries.incrementAndGet();
totalQueries.incrementAndGet();
lastQueryTime = System.currentTimeMillis();
}
public void decrementUsageCount(boolean unused) {
currentQueries.decrementAndGet();
if (unused)
totalQueries.decrementAndGet();
}
public boolean isAvailable() {
return state == DynamicSiteStatus.ONLINE;
}
public void markForRemoval() {
setState(DynamicSiteStatus.DELETED, true);
}
public boolean isMarkedForRemoval() {
return state == DynamicSiteStatus.DELETED;
}
public boolean isReadyForRemoval() {
return isMarkedForRemoval() && (currentQueries.get() == 0);
}
public CatalogEntity toCatalogEntity(String providerName, String poolName) {
ListOfPairs<String, Object> pairs = new ListOfPairs<String, Object>();
pairs.add(ShowSchema.GroupProviderSites.SITE_NAME, getFullName());
pairs.add(ShowSchema.GroupProviderSites.PROVIDER, providerName);
pairs.add(ShowSchema.GroupProviderSites.POOL, poolName);
pairs.add(ShowSchema.GroupProviderSites.NAME, getShortName());
pairs.add(ShowSchema.GroupProviderSites.URL, getUrl());
pairs.add(ShowSchema.GroupProviderSites.MAX_QUERIES, getMaxQueries());
pairs.add(ShowSchema.GroupProviderSites.CURRENT_QUERIES, getCurrentQueries());
pairs.add(ShowSchema.GroupProviderSites.TOTAL_QUERIES, getTotalQueries());
pairs.add(ShowSchema.GroupProviderSites.STATUS, getState().toString());
pairs.add(ShowSchema.GroupProviderSites.TIMESTAMP, getTimestamp());
return new AdhocCatalogEntity(pairs);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("name=" + getShortName());
sb.append(", url=" + getUrl());
sb.append(", user=" + getUser());
sb.append(", maxQueries=" + getMaxQueries());
sb.append(", currentQueries=" + getCurrentQueries());
sb.append(", state=" + getState().toString());
return sb.toString();
}
private static WorkerFactory factory = WorkerFactory.SINGLE_DIRECT_SINGLE_DIRECT_FACTORY;
@Override
public Worker createWorker(UserAuthentication auth, AdditionalConnectionInfo additionalConnInfo, EventLoopGroup preferredEventLoop) throws PEException {
// For dynamic sites we will use the site credentials rather than the
// ones passed in
return factory.newWorker(siteAuth, additionalConnInfo, this, preferredEventLoop);
}
@Override
public void onSiteFailure(CatalogDAO c) {
logger.error("Failure on dynamic site " + getShortName() + " (url= " + getMasterUrl() + ")");
this.setState(DynamicSiteStatus.FAILED, true);
}
@Override
public String getInstanceIdentifier() {
return getName();
}
@Override
public int getMasterInstanceId() {
return 0;
}
}