/*
* Copyright © 2015 Cask Data, Inc.
*
* 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 co.cask.cdap.data.tools;
import co.cask.cdap.api.common.Bytes;
import co.cask.cdap.common.namespace.NamespaceAdmin;
import co.cask.cdap.common.namespace.NamespacedLocationFactory;
import co.cask.cdap.data.stream.StreamUtils;
import co.cask.cdap.data2.util.TableId;
import co.cask.cdap.data2.util.hbase.HBaseTableUtil;
import co.cask.cdap.proto.Id;
import co.cask.cdap.proto.NamespaceMeta;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import org.apache.hadoop.conf.Configuration;
import org.apache.twill.filesystem.LocationFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
/**
* Upgrades stream state store table.
*
* Modifies all row keys from "namespace:foo/stream:bar".getBytes() to "stream:foo.bar".getBytes().
*/
public class StreamStateStoreUpgrader extends AbstractQueueUpgrader {
private static final Logger LOG = LoggerFactory.getLogger(StreamStateStoreUpgrader.class);
@Inject
public StreamStateStoreUpgrader(LocationFactory locationFactory, HBaseTableUtil tableUtil,
NamespacedLocationFactory namespacedLocationFactory, Configuration conf,
NamespaceAdmin namespaceAdmin) {
super(locationFactory, namespacedLocationFactory, tableUtil, conf, namespaceAdmin);
}
@Override
protected Iterable<TableId> getTableIds() throws Exception {
return Lists.transform(namespaceAdmin.list(), new Function<NamespaceMeta, TableId>() {
@Override
public TableId apply(NamespaceMeta input) {
return StreamUtils.getStateStoreTableId(Id.Namespace.from(input.getName()));
}
});
}
@Nullable
@Override
protected byte[] processRowKey(byte[] oldRowKey) {
LOG.debug("Processing stream state for: {}", Bytes.toString(oldRowKey));
Id.Stream streamId = fromRowKey(oldRowKey);
LOG.debug("Upgrading stream state for: {}", streamId);
return streamId == null ? null : streamId.toBytes();
}
@Nullable
private Id.Stream fromRowKey(byte[] oldRowKey) {
String oldKey = Bytes.toString(oldRowKey);
String[] oldParts = oldKey.split("/");
if (oldParts.length != 2) {
LOG.warn("Unknown format for row key: {}. Expected namespace:foo/stream:bar.", oldKey);
return null;
}
if (!oldParts[0].startsWith("namespace:") || !oldParts[1].startsWith("stream:")) {
LOG.warn("Unknown format for row key: {}. Expected namespace:foo/stream:bar.", oldKey);
return null;
}
String namespace = oldParts[0].substring("namespace:".length());
String stream = oldParts[1].substring("stream:".length());
return Id.Stream.from(namespace, stream);
}
}