blob: d91dbb56402856aa53afce5e69f76dd17b7dae10 [file] [log] [blame]
/*
* 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 org.apache.accumulo.core.clientImpl;
import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.LOCATION;
import static org.apache.accumulo.fate.util.UtilWaitThread.sleepUninterruptibly;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.Constants;
import org.apache.accumulo.core.clientImpl.TabletLocatorImpl.TabletServerLockChecker;
import org.apache.accumulo.core.data.Mutation;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.dataImpl.KeyExtent;
import org.apache.accumulo.core.metadata.RootTable;
import org.apache.accumulo.core.metadata.schema.Ample.ReadConsistency;
import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location;
import org.apache.accumulo.core.metadata.schema.TabletMetadata.LocationType;
import org.apache.accumulo.core.util.OpTimer;
import org.apache.accumulo.fate.zookeeper.ZooCache;
import org.apache.hadoop.io.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RootTabletLocator extends TabletLocator {
private final TabletServerLockChecker lockChecker;
RootTabletLocator(TabletServerLockChecker lockChecker) {
this.lockChecker = lockChecker;
}
@Override
public <T extends Mutation> void binMutations(ClientContext context, List<T> mutations,
Map<String,TabletServerMutations<T>> binnedMutations, List<T> failures) {
TabletLocation rootTabletLocation = getRootTabletLocation(context);
if (rootTabletLocation != null) {
TabletServerMutations<T> tsm = new TabletServerMutations<>(rootTabletLocation.tablet_session);
for (T mutation : mutations) {
tsm.addMutation(RootTable.EXTENT, mutation);
}
binnedMutations.put(rootTabletLocation.tablet_location, tsm);
} else {
failures.addAll(mutations);
}
}
@Override
public List<Range> binRanges(ClientContext context, List<Range> ranges,
Map<String,Map<KeyExtent,List<Range>>> binnedRanges) {
TabletLocation rootTabletLocation = getRootTabletLocation(context);
if (rootTabletLocation != null) {
for (Range range : ranges) {
TabletLocatorImpl.addRange(binnedRanges, rootTabletLocation.tablet_location,
RootTable.EXTENT, range);
}
return Collections.emptyList();
}
return ranges;
}
@Override
public void invalidateCache(KeyExtent failedExtent) {}
@Override
public void invalidateCache(Collection<KeyExtent> keySet) {}
@Override
public void invalidateCache(ClientContext context, String server) {
ZooCache zooCache = context.getZooCache();
String root = context.getZooKeeperRoot() + Constants.ZTSERVERS;
zooCache.clear(root + "/" + server);
}
@Override
public void invalidateCache() {}
protected TabletLocation getRootTabletLocation(ClientContext context) {
Logger log = LoggerFactory.getLogger(this.getClass());
OpTimer timer = null;
if (log.isTraceEnabled()) {
log.trace("tid={} Looking up root tablet location in zookeeper.",
Thread.currentThread().getId());
timer = new OpTimer().start();
}
Location loc = context.getAmple()
.readTablet(RootTable.EXTENT, ReadConsistency.EVENTUAL, LOCATION).getLocation();
if (timer != null) {
timer.stop();
log.trace("tid={} Found root tablet at {} in {}", Thread.currentThread().getId(), loc,
String.format("%.3f secs", timer.scale(TimeUnit.SECONDS)));
}
if (loc == null || loc.getType() != LocationType.CURRENT) {
return null;
}
String server = loc.getHostPort();
if (lockChecker.isLockHeld(server, loc.getSession()))
return new TabletLocation(RootTable.EXTENT, server, loc.getSession());
else
return null;
}
@Override
public TabletLocation locateTablet(ClientContext context, Text row, boolean skipRow,
boolean retry) {
TabletLocation location = getRootTabletLocation(context);
// Always retry when finding the root tablet
while (retry && location == null) {
sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
location = getRootTabletLocation(context);
}
return location;
}
}