HDFS-13478. RBF: Disabled Nameservice store API. Contributed by Inigo Goiri.

This commit is contained in:
Yiqun Lin 2018-04-21 13:19:09 +08:00
parent f40969a141
commit b6dae26f44
29 changed files with 1520 additions and 12 deletions

View File

@ -23,8 +23,14 @@
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.AddMountTableEntryRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.AddMountTableEntryResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisableNameserviceRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisableNameserviceResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnableNameserviceRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnableNameserviceResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnterSafeModeRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnterSafeModeResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetDisabledNameservicesRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetDisabledNameservicesResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetMountTableEntriesRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetMountTableEntriesResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetSafeModeRequestProto;
@ -38,8 +44,14 @@
import org.apache.hadoop.hdfs.server.federation.router.RouterAdminServer;
import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnterSafeModeRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnterSafeModeResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetSafeModeRequest;
@ -52,8 +64,14 @@
import org.apache.hadoop.hdfs.server.federation.store.protocol.UpdateMountTableEntryResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.AddMountTableEntryRequestPBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.AddMountTableEntryResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.DisableNameserviceRequestPBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.DisableNameserviceResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.EnableNameserviceRequestPBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.EnableNameserviceResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.EnterSafeModeRequestPBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.EnterSafeModeResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.GetDisabledNameservicesRequestPBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.GetDisabledNameservicesResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.GetMountTableEntriesRequestPBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.GetMountTableEntriesResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.GetSafeModeRequestPBImpl;
@ -208,4 +226,53 @@ public GetSafeModeResponseProto getSafeMode(RpcController controller,
throw new ServiceException(e);
}
}
@Override
public DisableNameserviceResponseProto disableNameservice(
RpcController controller, DisableNameserviceRequestProto request)
throws ServiceException {
try {
DisableNameserviceRequest req =
new DisableNameserviceRequestPBImpl(request);
DisableNameserviceResponse response = server.disableNameservice(req);
DisableNameserviceResponsePBImpl responsePB =
(DisableNameserviceResponsePBImpl) response;
return responsePB.getProto();
} catch (IOException e) {
throw new ServiceException(e);
}
}
@Override
public EnableNameserviceResponseProto enableNameservice(
RpcController controller, EnableNameserviceRequestProto request)
throws ServiceException {
try {
EnableNameserviceRequest req =
new EnableNameserviceRequestPBImpl(request);
EnableNameserviceResponse response = server.enableNameservice(req);
EnableNameserviceResponsePBImpl responsePB =
(EnableNameserviceResponsePBImpl) response;
return responsePB.getProto();
} catch (IOException e) {
throw new ServiceException(e);
}
}
@Override
public GetDisabledNameservicesResponseProto getDisabledNameservices(
RpcController controller, GetDisabledNameservicesRequestProto request)
throws ServiceException {
try {
GetDisabledNameservicesRequest req =
new GetDisabledNameservicesRequestPBImpl(request);
GetDisabledNameservicesResponse response =
server.getDisabledNameservices(req);
GetDisabledNameservicesResponsePBImpl responsePB =
(GetDisabledNameservicesResponsePBImpl)response;
return responsePB.getProto();
} catch (IOException e) {
throw new ServiceException(e);
}
}
}

View File

@ -24,8 +24,14 @@
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.AddMountTableEntryRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.AddMountTableEntryResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisableNameserviceRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisableNameserviceResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnableNameserviceRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnableNameserviceResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnterSafeModeRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnterSafeModeResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetDisabledNameservicesRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetDisabledNameservicesResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetMountTableEntriesRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetMountTableEntriesResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetSafeModeRequestProto;
@ -37,11 +43,18 @@
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.UpdateMountTableEntryRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.UpdateMountTableEntryResponseProto;
import org.apache.hadoop.hdfs.server.federation.resolver.MountTableManager;
import org.apache.hadoop.hdfs.server.federation.router.NameserviceManager;
import org.apache.hadoop.hdfs.server.federation.router.RouterStateManager;
import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnterSafeModeRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnterSafeModeResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetSafeModeRequest;
@ -54,7 +67,12 @@
import org.apache.hadoop.hdfs.server.federation.store.protocol.UpdateMountTableEntryResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.AddMountTableEntryRequestPBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.AddMountTableEntryResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.DisableNameserviceRequestPBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.DisableNameserviceResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.EnableNameserviceRequestPBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.EnableNameserviceResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.EnterSafeModeResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.GetDisabledNameservicesResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.GetMountTableEntriesRequestPBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.GetMountTableEntriesResponsePBImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.GetSafeModeResponsePBImpl;
@ -80,7 +98,7 @@
@InterfaceStability.Stable
public class RouterAdminProtocolTranslatorPB
implements ProtocolMetaInterface, MountTableManager,
Closeable, ProtocolTranslator, RouterStateManager {
Closeable, ProtocolTranslator, RouterStateManager, NameserviceManager {
final private RouterAdminProtocolPB rpcProxy;
public RouterAdminProtocolTranslatorPB(RouterAdminProtocolPB proxy) {
@ -205,4 +223,48 @@ public GetSafeModeResponse getSafeMode(GetSafeModeRequest request)
throw new IOException(ProtobufHelper.getRemoteException(e).getMessage());
}
}
@Override
public DisableNameserviceResponse disableNameservice(
DisableNameserviceRequest request) throws IOException {
DisableNameserviceRequestPBImpl requestPB =
(DisableNameserviceRequestPBImpl)request;
DisableNameserviceRequestProto proto = requestPB.getProto();
try {
DisableNameserviceResponseProto response =
rpcProxy.disableNameservice(null, proto);
return new DisableNameserviceResponsePBImpl(response);
} catch (ServiceException e) {
throw new IOException(ProtobufHelper.getRemoteException(e).getMessage());
}
}
@Override
public EnableNameserviceResponse enableNameservice(
EnableNameserviceRequest request) throws IOException {
EnableNameserviceRequestPBImpl requestPB =
(EnableNameserviceRequestPBImpl)request;
EnableNameserviceRequestProto proto = requestPB.getProto();
try {
EnableNameserviceResponseProto response =
rpcProxy.enableNameservice(null, proto);
return new EnableNameserviceResponsePBImpl(response);
} catch (ServiceException e) {
throw new IOException(ProtobufHelper.getRemoteException(e).getMessage());
}
}
@Override
public GetDisabledNameservicesResponse getDisabledNameservices(
GetDisabledNameservicesRequest request) throws IOException {
GetDisabledNameservicesRequestProto proto =
GetDisabledNameservicesRequestProto.newBuilder().build();
try {
GetDisabledNameservicesResponseProto response =
rpcProxy.getDisabledNameservices(null, proto);
return new GetDisabledNameservicesResponsePBImpl(response);
} catch (ServiceException e) {
throw new IOException(ProtobufHelper.getRemoteException(e).getMessage());
}
}
}

View File

@ -0,0 +1,51 @@
/**
* 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.hadoop.hdfs.server.federation.router;
import java.io.IOException;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesResponse;
/**
* Interface for enable/disable name service.
*/
public interface NameserviceManager {
/**
* Disable a name service.
*/
DisableNameserviceResponse disableNameservice(
DisableNameserviceRequest request) throws IOException;
/**
* Enable a name service.
*/
EnableNameserviceResponse enableNameservice(EnableNameserviceRequest request)
throws IOException;
/**
* Get the list of disabled name service.
*/
GetDisabledNameservicesResponse getDisabledNameservices(
GetDisabledNameservicesRequest request) throws IOException;
}

View File

@ -22,6 +22,7 @@
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Set;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.DFSConfigKeys;
@ -29,11 +30,18 @@
import org.apache.hadoop.hdfs.protocolPB.RouterAdminProtocolPB;
import org.apache.hadoop.hdfs.protocolPB.RouterAdminProtocolServerSideTranslatorPB;
import org.apache.hadoop.hdfs.server.federation.resolver.MountTableManager;
import org.apache.hadoop.hdfs.server.federation.store.DisabledNameserviceStore;
import org.apache.hadoop.hdfs.server.federation.store.MountTableStore;
import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnterSafeModeRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnterSafeModeResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetSafeModeRequest;
@ -62,7 +70,7 @@
* router. It is created, started, and stopped by {@link Router}.
*/
public class RouterAdminServer extends AbstractService
implements MountTableManager, RouterStateManager {
implements MountTableManager, RouterStateManager, NameserviceManager {
private static final Logger LOG =
LoggerFactory.getLogger(RouterAdminServer.class);
@ -73,6 +81,8 @@ public class RouterAdminServer extends AbstractService
private MountTableStore mountTableStore;
private DisabledNameserviceStore disabledStore;
/** The Admin server that listens to requests from clients. */
private final Server adminServer;
private final InetSocketAddress adminAddress;
@ -166,6 +176,19 @@ private MountTableStore getMountTableStore() throws IOException {
return this.mountTableStore;
}
private DisabledNameserviceStore getDisabledNameserviceStore()
throws IOException {
if (this.disabledStore == null) {
this.disabledStore = router.getStateStore().getRegisteredRecordStore(
DisabledNameserviceStore.class);
if (this.disabledStore == null) {
throw new IOException(
"Disabled Nameservice state store is not available.");
}
}
return this.disabledStore;
}
/**
* Get the RPC address of the admin service.
* @return Administration service RPC address.
@ -256,6 +279,34 @@ private boolean verifySafeMode(boolean isInSafeMode) {
&& !serverInSafeMode);
}
@Override
public DisableNameserviceResponse disableNameservice(
DisableNameserviceRequest request) throws IOException {
// TODO check permissions
String nsId = request.getNameServiceId();
// TODO check that the name service exists
boolean success = getDisabledNameserviceStore().disableNameservice(nsId);
return DisableNameserviceResponse.newInstance(success);
}
@Override
public EnableNameserviceResponse enableNameservice(
EnableNameserviceRequest request) throws IOException {
// TODO check permissions
String nsId = request.getNameServiceId();
// TODO check that the name service exists
boolean success = getDisabledNameserviceStore().enableNameservice(nsId);
return EnableNameserviceResponse.newInstance(success);
}
@Override
public GetDisabledNameservicesResponse getDisabledNameservices(
GetDisabledNameservicesRequest request) throws IOException {
// TODO check permissions
Set<String> nsIds = getDisabledNameserviceStore().getDisabledNameservices();
return GetDisabledNameservicesResponse.newInstance(nsIds);
}
/**
* Get a new permission checker used for making mount table access
* control. This method will be invoked during each RPC call in router

View File

@ -73,6 +73,10 @@ public RouterStateManager getRouterStateManager() {
return proxy;
}
public NameserviceManager getNameserviceManager() {
return proxy;
}
@Override
public synchronized void close() throws IOException {
RPC.stopProxy(proxy);

View File

@ -0,0 +1,65 @@
/**
* 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.hadoop.hdfs.server.federation.store;
import java.io.IOException;
import java.util.Set;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.hdfs.server.federation.store.driver.StateStoreDriver;
import org.apache.hadoop.hdfs.server.federation.store.records.DisabledNameservice;
/**
* State store record to track disabled name services.
*/
@InterfaceAudience.Private
@InterfaceStability.Evolving
public abstract class DisabledNameserviceStore
extends CachedRecordStore<DisabledNameservice> {
public DisabledNameserviceStore(StateStoreDriver driver) {
super(DisabledNameservice.class, driver);
}
/**
* Disable a name service.
*
* @param nsId Identifier of the name service.
* @return If the name service was successfully disabled.
* @throws IOException If the state store could not be queried.
*/
public abstract boolean disableNameservice(String nsId) throws IOException;
/**
* Enable a name service.
*
* @param nsId Identifier of the name service.
* @return If the name service was successfully brought back.
* @throws IOException If the state store could not be queried.
*/
public abstract boolean enableNameservice(String nsId) throws IOException;
/**
* Get a list of disabled name services.
*
* @return List of disabled name services.
* @throws IOException If the state store could not be queried.
*/
public abstract Set<String> getDisabledNameservices() throws IOException;
}

View File

@ -37,6 +37,7 @@
import org.apache.hadoop.hdfs.server.federation.metrics.StateStoreMetrics;
import org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys;
import org.apache.hadoop.hdfs.server.federation.store.driver.StateStoreDriver;
import org.apache.hadoop.hdfs.server.federation.store.impl.DisabledNameserviceStoreImpl;
import org.apache.hadoop.hdfs.server.federation.store.impl.MembershipStoreImpl;
import org.apache.hadoop.hdfs.server.federation.store.impl.MountTableStoreImpl;
import org.apache.hadoop.hdfs.server.federation.store.impl.RouterStoreImpl;
@ -75,6 +76,7 @@
* See {@link org.apache.hadoop.fs.viewfs.ViewFs ViewFs}.
* <li>{@link RebalancerStore}: Log of the rebalancing operations.
* <li>{@link RouterStore}: Router state in the federation.
* <li>{@link DisabledNameserviceStore}: Disabled name services.
* <li>{@link TokenStore}: Tokens in the federation.
* </ul>
*/
@ -152,6 +154,7 @@ protected void serviceInit(Configuration config) throws Exception {
addRecordStore(MembershipStoreImpl.class);
addRecordStore(MountTableStoreImpl.class);
addRecordStore(RouterStoreImpl.class);
addRecordStore(DisabledNameserviceStoreImpl.class);
// Check the connection to the State Store periodically
this.monitorService = new StateStoreConnectionMonitorService(this);

View File

@ -0,0 +1,68 @@
/**
* 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.hadoop.hdfs.server.federation.store.impl;
import java.io.IOException;
import java.util.Set;
import java.util.TreeSet;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.hdfs.server.federation.store.DisabledNameserviceStore;
import org.apache.hadoop.hdfs.server.federation.store.driver.StateStoreDriver;
import org.apache.hadoop.hdfs.server.federation.store.records.DisabledNameservice;
/**
* Implementation of {@link DisabledNameserviceStore}.
*/
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class DisabledNameserviceStoreImpl extends DisabledNameserviceStore {
public DisabledNameserviceStoreImpl(StateStoreDriver driver) {
super(driver);
}
@Override
public boolean disableNameservice(String nsId)
throws IOException {
DisabledNameservice record =
DisabledNameservice.newInstance(nsId);
return getDriver().put(record, false, false);
}
@Override
public boolean enableNameservice(String nsId)
throws IOException {
DisabledNameservice record =
DisabledNameservice.newInstance(nsId);
return getDriver().remove(record);
}
@Override
public Set<String> getDisabledNameservices() throws IOException {
Set<String> disabledNameservices = new TreeSet<>();
for (DisabledNameservice record : getCachedRecords()) {
String nsId = record.getNameserviceId();
disabledNameservices.add(nsId);
}
return disabledNameservices;
}
}

View File

@ -0,0 +1,47 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol;
import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.hdfs.server.federation.store.driver.StateStoreSerializer;
/**
* API request for disabling a name service and updating its state in the
* State Store.
*/
public abstract class DisableNameserviceRequest {
public static DisableNameserviceRequest newInstance() {
return StateStoreSerializer.newRecord(DisableNameserviceRequest.class);
}
public static DisableNameserviceRequest newInstance(String nsId) {
DisableNameserviceRequest request = newInstance();
request.setNameServiceId(nsId);
return request;
}
@Public
@Unstable
public abstract String getNameServiceId();
@Public
@Unstable
public abstract void setNameServiceId(String nsId);
}

View File

@ -0,0 +1,50 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol;
import java.io.IOException;
import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.hdfs.server.federation.store.driver.StateStoreSerializer;
/**
* API response for disabling a name service and updating its state in the
* State Store.
*/
public abstract class DisableNameserviceResponse {
public static DisableNameserviceResponse newInstance() throws IOException {
return StateStoreSerializer.newRecord(DisableNameserviceResponse.class);
}
public static DisableNameserviceResponse newInstance(boolean status)
throws IOException {
DisableNameserviceResponse response = newInstance();
response.setStatus(status);
return response;
}
@Public
@Unstable
public abstract boolean getStatus();
@Public
@Unstable
public abstract void setStatus(boolean result);
}

View File

@ -0,0 +1,47 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol;
import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.hdfs.server.federation.store.driver.StateStoreSerializer;
/**
* API request for enabling a name service and updating its state in the
* State Store.
*/
public abstract class EnableNameserviceRequest {
public static EnableNameserviceRequest newInstance() {
return StateStoreSerializer.newRecord(EnableNameserviceRequest.class);
}
public static EnableNameserviceRequest newInstance(String nsId) {
EnableNameserviceRequest request = newInstance();
request.setNameServiceId(nsId);
return request;
}
@Public
@Unstable
public abstract String getNameServiceId();
@Public
@Unstable
public abstract void setNameServiceId(String nsId);
}

View File

@ -0,0 +1,50 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol;
import java.io.IOException;
import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.hdfs.server.federation.store.driver.StateStoreSerializer;
/**
* API response for enabling a name service and updating its state in the
* State Store.
*/
public abstract class EnableNameserviceResponse {
public static EnableNameserviceResponse newInstance() throws IOException {
return StateStoreSerializer.newRecord(EnableNameserviceResponse.class);
}
public static EnableNameserviceResponse newInstance(boolean status)
throws IOException {
EnableNameserviceResponse response = newInstance();
response.setStatus(status);
return response;
}
@Public
@Unstable
public abstract boolean getStatus();
@Public
@Unstable
public abstract void setStatus(boolean result);
}

View File

@ -0,0 +1,30 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol;
import org.apache.hadoop.hdfs.server.federation.store.driver.StateStoreSerializer;
/**
* API request for getting the disabled name services.
*/
public abstract class GetDisabledNameservicesRequest {
public static GetDisabledNameservicesRequest newInstance() {
return StateStoreSerializer.newRecord(GetDisabledNameservicesRequest.class);
}
}

View File

@ -0,0 +1,51 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol;
import java.util.Set;
import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.hdfs.server.federation.store.driver.StateStoreSerializer;
/**
* API response for getting the disabled nameservices in the state store.
*/
public abstract class GetDisabledNameservicesResponse {
public static GetDisabledNameservicesResponse newInstance() {
return StateStoreSerializer.newRecord(
GetDisabledNameservicesResponse.class);
}
public static GetDisabledNameservicesResponse newInstance(
Set<String> nsIds) {
GetDisabledNameservicesResponse response = newInstance();
response.setNameservices(nsIds);
return response;
}
@Public
@Unstable
public abstract Set<String> getNameservices();
@Public
@Unstable
public abstract void setNameservices(Set<String> nameservices);
}

View File

@ -0,0 +1,73 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol.impl.pb;
import java.io.IOException;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisableNameserviceRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisableNameserviceRequestProto.Builder;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisableNameserviceRequestProtoOrBuilder;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.records.impl.pb.PBRecord;
import com.google.protobuf.Message;
/**
* Protobuf implementation of the state store API object
* DisableNameserviceRequest.
*/
public class DisableNameserviceRequestPBImpl extends DisableNameserviceRequest
implements PBRecord {
private FederationProtocolPBTranslator<DisableNameserviceRequestProto,
Builder, DisableNameserviceRequestProtoOrBuilder> translator =
new FederationProtocolPBTranslator<>(
DisableNameserviceRequestProto.class);
public DisableNameserviceRequestPBImpl() {
}
public DisableNameserviceRequestPBImpl(DisableNameserviceRequestProto proto) {
this.translator.setProto(proto);
}
@Override
public DisableNameserviceRequestProto getProto() {
return translator.build();
}
@Override
public void setProto(Message proto) {
this.translator.setProto(proto);
}
@Override
public void readInstance(String base64String) throws IOException {
this.translator.readInstance(base64String);
}
@Override
public String getNameServiceId() {
return this.translator.getProtoOrBuilder().getNameServiceId();
}
@Override
public void setNameServiceId(String nsId) {
this.translator.getBuilder().setNameServiceId(nsId);
}
}

View File

@ -0,0 +1,74 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol.impl.pb;
import java.io.IOException;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisableNameserviceResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisableNameserviceResponseProto.Builder;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisableNameserviceResponseProtoOrBuilder;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.records.impl.pb.PBRecord;
import com.google.protobuf.Message;
/**
* Protobuf implementation of the state store API object
* {@link DisableNameserviceResponse}.
*/
public class DisableNameserviceResponsePBImpl
extends DisableNameserviceResponse implements PBRecord {
private FederationProtocolPBTranslator<DisableNameserviceResponseProto,
Builder, DisableNameserviceResponseProtoOrBuilder> translator =
new FederationProtocolPBTranslator<>(
DisableNameserviceResponseProto.class);
public DisableNameserviceResponsePBImpl() {
}
public DisableNameserviceResponsePBImpl(
DisableNameserviceResponseProto proto) {
this.translator.setProto(proto);
}
@Override
public DisableNameserviceResponseProto getProto() {
return translator.build();
}
@Override
public void setProto(Message proto) {
this.translator.setProto(proto);
}
@Override
public void readInstance(String base64String) throws IOException {
this.translator.readInstance(base64String);
}
@Override
public boolean getStatus() {
return this.translator.getProtoOrBuilder().getStatus();
}
@Override
public void setStatus(boolean status) {
this.translator.getBuilder().setStatus(status);
}
}

View File

@ -0,0 +1,73 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol.impl.pb;
import java.io.IOException;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnableNameserviceRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnableNameserviceRequestProto.Builder;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnableNameserviceRequestProtoOrBuilder;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.records.impl.pb.PBRecord;
import com.google.protobuf.Message;
/**
* Protobuf implementation of the state store API object
* EnableNameserviceRequest.
*/
public class EnableNameserviceRequestPBImpl extends EnableNameserviceRequest
implements PBRecord {
private FederationProtocolPBTranslator<EnableNameserviceRequestProto,
Builder, EnableNameserviceRequestProtoOrBuilder> translator =
new FederationProtocolPBTranslator<>(
EnableNameserviceRequestProto.class);
public EnableNameserviceRequestPBImpl() {
}
public EnableNameserviceRequestPBImpl(EnableNameserviceRequestProto proto) {
this.translator.setProto(proto);
}
@Override
public EnableNameserviceRequestProto getProto() {
return translator.build();
}
@Override
public void setProto(Message proto) {
this.translator.setProto(proto);
}
@Override
public void readInstance(String base64String) throws IOException {
this.translator.readInstance(base64String);
}
@Override
public String getNameServiceId() {
return this.translator.getProtoOrBuilder().getNameServiceId();
}
@Override
public void setNameServiceId(String nsId) {
this.translator.getBuilder().setNameServiceId(nsId);
}
}

View File

@ -0,0 +1,73 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol.impl.pb;
import java.io.IOException;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnableNameserviceResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnableNameserviceResponseProto.Builder;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.EnableNameserviceResponseProtoOrBuilder;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.records.impl.pb.PBRecord;
import com.google.protobuf.Message;
/**
* Protobuf implementation of the state store API object
* EnableNameserviceResponse.
*/
public class EnableNameserviceResponsePBImpl extends EnableNameserviceResponse
implements PBRecord {
private FederationProtocolPBTranslator<EnableNameserviceResponseProto,
Builder, EnableNameserviceResponseProtoOrBuilder> translator =
new FederationProtocolPBTranslator<>(
EnableNameserviceResponseProto.class);
public EnableNameserviceResponsePBImpl() {
}
public EnableNameserviceResponsePBImpl(EnableNameserviceResponseProto proto) {
this.translator.setProto(proto);
}
@Override
public EnableNameserviceResponseProto getProto() {
return translator.build();
}
@Override
public void setProto(Message proto) {
this.translator.setProto(proto);
}
@Override
public void readInstance(String base64String) throws IOException {
this.translator.readInstance(base64String);
}
@Override
public boolean getStatus() {
return this.translator.getProtoOrBuilder().getStatus();
}
@Override
public void setStatus(boolean status) {
this.translator.getBuilder().setStatus(status);
}
}

View File

@ -0,0 +1,66 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol.impl.pb;
import java.io.IOException;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetDisabledNameservicesRequestProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetDisabledNameservicesRequestProto.Builder;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetDisabledNameservicesRequestProtoOrBuilder;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesRequest;
import org.apache.hadoop.hdfs.server.federation.store.records.impl.pb.PBRecord;
import com.google.protobuf.Message;
/**
* Protobuf implementation of the state store API object
* GetDisabledNameservicesRequest.
*/
public class GetDisabledNameservicesRequestPBImpl
extends GetDisabledNameservicesRequest implements PBRecord {
private FederationProtocolPBTranslator<GetDisabledNameservicesRequestProto,
Builder, GetDisabledNameservicesRequestProtoOrBuilder> translator =
new FederationProtocolPBTranslator<>(
GetDisabledNameservicesRequestProto.class);
public GetDisabledNameservicesRequestPBImpl() {
// As this request has no parameter, we need to initialize it
this.translator.getBuilder();
}
public GetDisabledNameservicesRequestPBImpl(
GetDisabledNameservicesRequestProto proto) {
this.translator.setProto(proto);
}
@Override
public GetDisabledNameservicesRequestProto getProto() {
return translator.build();
}
@Override
public void setProto(Message proto) {
this.translator.setProto(proto);
}
@Override
public void readInstance(String base64String) throws IOException {
this.translator.readInstance(base64String);
}
}

View File

@ -0,0 +1,84 @@
/**
* 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.hadoop.hdfs.server.federation.store.protocol.impl.pb;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetDisabledNameservicesResponseProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetDisabledNameservicesResponseProto.*;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.GetDisabledNameservicesResponseProtoOrBuilder;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesResponse;
import org.apache.hadoop.hdfs.server.federation.store.records.impl.pb.PBRecord;
import com.google.protobuf.Message;
/**
* Protobuf implementation of the state store API object
* GetDisabledNameservicesResponse.
*/
public class GetDisabledNameservicesResponsePBImpl
extends GetDisabledNameservicesResponse implements PBRecord {
private FederationProtocolPBTranslator<GetDisabledNameservicesResponseProto,
Builder, GetDisabledNameservicesResponseProtoOrBuilder> translator =
new FederationProtocolPBTranslator<
GetDisabledNameservicesResponseProto, Builder,
GetDisabledNameservicesResponseProtoOrBuilder>(
GetDisabledNameservicesResponseProto.class);
public GetDisabledNameservicesResponsePBImpl() {
}
public GetDisabledNameservicesResponsePBImpl(
GetDisabledNameservicesResponseProto proto) {
this.translator.setProto(proto);
}
@Override
public GetDisabledNameservicesResponseProto getProto() {
return this.translator.build();
}
@Override
public void setProto(Message proto) {
this.translator.setProto(proto);
}
@Override
public void readInstance(String base64String) throws IOException {
this.translator.readInstance(base64String);
}
@Override
public Set<String> getNameservices() {
List<String> nsIds =
this.translator.getProtoOrBuilder().getNameServiceIdsList();
return new TreeSet<>(nsIds);
}
@Override
public void setNameservices(Set<String> nameservices) {
this.translator.getBuilder().clearNameServiceIds();
for (String nsId : nameservices) {
this.translator.getBuilder().addNameServiceIds(nsId);
}
}
}

View File

@ -21,6 +21,8 @@
import org.apache.hadoop.util.Time;
import com.google.common.annotations.VisibleForTesting;
/**
* Abstract base of a data record in the StateStore. All StateStore records are
* derived from this class. Data records are persisted in the data store and
@ -109,6 +111,17 @@ public String getPrimaryKey() {
return generateMashupKey(getPrimaryKeys());
}
/**
* If the record has fields others than the primary keys. This is used by
* TestStateStoreDriverBase to skip the modification check.
*
* @return If the record has more fields.
*/
@VisibleForTesting
public boolean hasOtherFields() {
return true;
}
/**
* Generates a cache key from a map of values.
*

View File

@ -0,0 +1,81 @@
/**
* 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.hadoop.hdfs.server.federation.store.records;
import java.io.IOException;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.hadoop.hdfs.server.federation.store.driver.StateStoreSerializer;
/**
* Data record indicating a specific name service ID has been disabled and
* is no longer valid. Allows quick disabling of name services.
*/
public abstract class DisabledNameservice extends BaseRecord {
public DisabledNameservice() {
super();
}
public static DisabledNameservice newInstance() throws IOException {
DisabledNameservice record =
StateStoreSerializer.newRecord(DisabledNameservice.class);
record.init();
return record;
}
public static DisabledNameservice newInstance(String nsId)
throws IOException {
DisabledNameservice record = newInstance();
record.setNameserviceId(nsId);
return record;
}
/**
* Get the identifier of the name service to disable.
*
* @return Identifier of the name service to disable.
*/
public abstract String getNameserviceId();
/**
* Set the identifier of the name service to disable.
*
* @param nameServiceId Identifier of the name service to disable.
*/
public abstract void setNameserviceId(String nameServiceId);
@Override
public SortedMap<String, String> getPrimaryKeys() {
SortedMap<String, String> keyMap = new TreeMap<>();
keyMap.put("nameServiceId", this.getNameserviceId());
return keyMap;
}
@Override
public boolean hasOtherFields() {
// We don't have fields other than the primary keys
return false;
}
@Override
public long getExpirationMs() {
return -1;
}
}

View File

@ -0,0 +1,95 @@
/**
* 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.hadoop.hdfs.server.federation.store.records.impl.pb;
import java.io.IOException;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisabledNameserviceRecordProto;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisabledNameserviceRecordProto.Builder;
import org.apache.hadoop.hdfs.federation.protocol.proto.HdfsServerFederationProtos.DisabledNameserviceRecordProtoOrBuilder;
import org.apache.hadoop.hdfs.server.federation.store.protocol.impl.pb.FederationProtocolPBTranslator;
import org.apache.hadoop.hdfs.server.federation.store.records.DisabledNameservice;
import com.google.protobuf.Message;
/**
* Protobuf implementation of the {@link DisabledNameservice} record.
*/
public class DisabledNameservicePBImpl extends DisabledNameservice
implements PBRecord {
private FederationProtocolPBTranslator<DisabledNameserviceRecordProto,
Builder, DisabledNameserviceRecordProtoOrBuilder> translator =
new FederationProtocolPBTranslator<
DisabledNameserviceRecordProto, Builder,
DisabledNameserviceRecordProtoOrBuilder>(
DisabledNameserviceRecordProto.class);
public DisabledNameservicePBImpl() {
}
public DisabledNameservicePBImpl(
DisabledNameserviceRecordProto proto) {
this.translator.setProto(proto);
}
@Override
public DisabledNameserviceRecordProto getProto() {
return this.translator.build();
}
@Override
public void setProto(Message proto) {
this.translator.setProto(proto);
}
@Override
public void readInstance(String base64String) throws IOException {
this.translator.readInstance(base64String);
}
@Override
public String getNameserviceId() {
return this.translator.getProtoOrBuilder().getNameServiceId();
}
@Override
public void setNameserviceId(String nameServiceId) {
this.translator.getBuilder().setNameServiceId(nameServiceId);
}
@Override
public void setDateModified(long time) {
this.translator.getBuilder().setDateModified(time);
}
@Override
public long getDateModified() {
return this.translator.getProtoOrBuilder().getDateModified();
}
@Override
public void setDateCreated(long time) {
this.translator.getBuilder().setDateCreated(time);
}
@Override
public long getDateCreated() {
return this.translator.getProtoOrBuilder().getDateCreated();
}
}

View File

@ -32,14 +32,21 @@
import org.apache.hadoop.hdfs.server.federation.resolver.MountTableManager;
import org.apache.hadoop.hdfs.server.federation.resolver.RemoteLocation;
import org.apache.hadoop.hdfs.server.federation.resolver.order.DestinationOrder;
import org.apache.hadoop.hdfs.server.federation.router.RouterClient;
import org.apache.hadoop.hdfs.server.federation.router.NameserviceManager;
import org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys;
import org.apache.hadoop.hdfs.server.federation.router.RouterClient;
import org.apache.hadoop.hdfs.server.federation.router.RouterQuotaUsage;
import org.apache.hadoop.hdfs.server.federation.router.RouterStateManager;
import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnterSafeModeRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnterSafeModeResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetSafeModeRequest;
@ -95,7 +102,9 @@ public void printUsage() {
+ "\t[-setQuota <path> -nsQuota <nsQuota> -ssQuota "
+ "<quota in bytes or quota size string>]\n"
+ "\t[-clrQuota <path>]\n"
+ "\t[-safemode enter | leave | get]\n";
+ "\t[-safemode enter | leave | get]\n"
+ "\t[-nameservice enable | disable <nameservice>]\n"
+ "\t[-getDisabledNameservices]\n";
System.out.println(usage);
}
@ -143,6 +152,12 @@ public int run(String[] argv) throws Exception {
printUsage();
return exitCode;
}
} else if ("-nameservice".equalsIgnoreCase(cmd)) {
if (argv.length < 3) {
System.err.println("Not enough parameters specificed for cmd " + cmd);
printUsage();
return exitCode;
}
}
// Initialize RouterClient
@ -190,6 +205,12 @@ public int run(String[] argv) throws Exception {
}
} else if ("-safemode".equals(cmd)) {
manageSafeMode(argv[i]);
} else if ("-nameservice".equals(cmd)) {
String subcmd = argv[i];
String nsId = argv[i + 1];
manageNameservice(subcmd, nsId);
} else if ("-getDisabledNameservices".equals(cmd)) {
getDisabledNameservices();
} else {
printUsage();
return exitCode;
@ -611,6 +632,57 @@ private boolean getSafeMode() throws IOException {
return response.isInSafeMode();
}
/**
* Manage the name service: enabling/disabling.
* @param cmd Input command, disable or enable.
* @throws IOException
*/
private void manageNameservice(String cmd, String nsId) throws IOException {
if (cmd.equals("enable")) {
if (enableNameservice(nsId)) {
System.out.println("Successfully enabled nameservice " + nsId);
} else {
System.err.println("Cannot enable " + nsId);
}
} else if (cmd.equals("disable")) {
if (disableNameservice(nsId)) {
System.out.println("Successfully disabled nameservice " + nsId);
} else {
System.err.println("Cannot disable " + nsId);
}
} else {
throw new IllegalArgumentException("Unknown command: " + cmd);
}
}
private boolean disableNameservice(String nsId) throws IOException {
NameserviceManager nameserviceManager = client.getNameserviceManager();
DisableNameserviceResponse response =
nameserviceManager.disableNameservice(
DisableNameserviceRequest.newInstance(nsId));
return response.getStatus();
}
private boolean enableNameservice(String nsId) throws IOException {
NameserviceManager nameserviceManager = client.getNameserviceManager();
EnableNameserviceResponse response =
nameserviceManager.enableNameservice(
EnableNameserviceRequest.newInstance(nsId));
return response.getStatus();
}
private void getDisabledNameservices() throws IOException {
NameserviceManager nameserviceManager = client.getNameserviceManager();
GetDisabledNameservicesRequest request =
GetDisabledNameservicesRequest.newInstance();
GetDisabledNameservicesResponse response =
nameserviceManager.getDisabledNameservices(request);
System.out.println("List of disabled nameservices:");
for (String nsId : response.getNameservices()) {
System.out.println(nsId);
}
}
/**
* Inner class that stores ACL info of mount table.
*/

View File

@ -243,3 +243,36 @@ message GetSafeModeRequestProto {
message GetSafeModeResponseProto {
optional bool isInSafeMode = 1;
}
/////////////////////////////////////////////////
// Disabled Nameservice State
/////////////////////////////////////////////////
message DisabledNameserviceRecordProto {
optional uint64 dateCreated = 1;
optional uint64 dateModified = 2;
optional string nameServiceId = 3;
}
message DisableNameserviceRequestProto {
optional string nameServiceId = 1;
}
message DisableNameserviceResponseProto {
optional bool status = 1;
}
message EnableNameserviceRequestProto {
optional string nameServiceId = 1;
}
message EnableNameserviceResponseProto {
optional bool status = 1;
}
message GetDisabledNameservicesRequestProto {
}
message GetDisabledNameservicesResponseProto {
repeated string nameServiceIds = 1;
}

View File

@ -59,4 +59,19 @@ service RouterAdminProtocolService {
* Verify if current Router state is safe mode state.
*/
rpc getSafeMode(GetSafeModeRequestProto) returns (GetSafeModeResponseProto);
/**
* Disable a name service.
*/
rpc disableNameservice(DisableNameserviceRequestProto) returns (DisableNameserviceResponseProto);
/**
* Enable a name service.
*/
rpc enableNameservice(EnableNameserviceRequestProto) returns (EnableNameserviceResponseProto);
/**
* Get the list of disabled name services.
*/
rpc getDisabledNameservices(GetDisabledNameservicesRequestProto) returns (GetDisabledNameservicesResponseProto);
}

View File

@ -26,6 +26,7 @@
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.server.federation.RouterConfigBuilder;
@ -35,9 +36,16 @@
import org.apache.hadoop.hdfs.server.federation.resolver.RemoteLocation;
import org.apache.hadoop.hdfs.server.federation.resolver.order.DestinationOrder;
import org.apache.hadoop.hdfs.server.federation.store.StateStoreService;
import org.apache.hadoop.hdfs.server.federation.store.impl.DisabledNameserviceStoreImpl;
import org.apache.hadoop.hdfs.server.federation.store.impl.MountTableStoreImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.AddMountTableEntryResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.DisableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.EnableNameserviceResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetDisabledNameservicesResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesResponse;
import org.apache.hadoop.hdfs.server.federation.store.protocol.RemoveMountTableEntryRequest;
@ -337,4 +345,45 @@ private List<MountTable> getMountTableEntries(MountTableManager mountTable,
mountTable.getMountTableEntries(request);
return response.getEntries();
}
@Test
public void testNameserviceManager() throws IOException {
RouterClient client = routerContext.getAdminClient();
NameserviceManager nsManager = client.getNameserviceManager();
// There shouldn't be any name service disabled
Set<String> disabled = getDisabledNameservices(nsManager);
assertTrue(disabled.isEmpty());
// Disable one and see it
DisableNameserviceRequest disableReq =
DisableNameserviceRequest.newInstance("ns0");
DisableNameserviceResponse disableResp =
nsManager.disableNameservice(disableReq);
assertTrue(disableResp.getStatus());
// Refresh the cache
disabled = getDisabledNameservices(nsManager);
assertEquals(1, disabled.size());
assertTrue(disabled.contains("ns0"));
// Enable one and we should have no disabled name services
EnableNameserviceRequest enableReq =
EnableNameserviceRequest.newInstance("ns0");
EnableNameserviceResponse enableResp =
nsManager.enableNameservice(enableReq);
assertTrue(enableResp.getStatus());
disabled = getDisabledNameservices(nsManager);
assertTrue(disabled.isEmpty());
}
private Set<String> getDisabledNameservices(NameserviceManager nsManager)
throws IOException {
stateStore.loadCache(DisabledNameserviceStoreImpl.class, true);
GetDisabledNameservicesRequest getReq =
GetDisabledNameservicesRequest.newInstance();
GetDisabledNameservicesResponse response =
nsManager.getDisabledNameservices(getReq);
return response.getNameservices();
}
}

View File

@ -22,20 +22,20 @@
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
import org.apache.hadoop.hdfs.server.federation.RouterConfigBuilder;
import org.apache.hadoop.hdfs.server.federation.MiniRouterDFSCluster.RouterContext;
import org.apache.hadoop.hdfs.server.federation.RouterConfigBuilder;
import org.apache.hadoop.hdfs.server.federation.StateStoreDFSCluster;
import org.apache.hadoop.hdfs.server.federation.resolver.MountTableManager;
import org.apache.hadoop.hdfs.server.federation.resolver.RemoteLocation;
import org.apache.hadoop.hdfs.server.federation.resolver.order.DestinationOrder;
import org.apache.hadoop.hdfs.server.federation.store.StateStoreService;
import org.apache.hadoop.hdfs.server.federation.store.impl.DisabledNameserviceStoreImpl;
import org.apache.hadoop.hdfs.server.federation.store.impl.MountTableStoreImpl;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesRequest;
import org.apache.hadoop.hdfs.server.federation.store.protocol.GetMountTableEntriesResponse;
@ -65,7 +65,9 @@ public class TestRouterAdminCLI {
private static final String TEST_USER = "test-user";
private final ByteArrayOutputStream out = new ByteArrayOutputStream();
private final ByteArrayOutputStream err = new ByteArrayOutputStream();
private static final PrintStream OLD_OUT = System.out;
private static final PrintStream OLD_ERR = System.err;
@BeforeClass
public static void globalSetUp() throws Exception {
@ -102,8 +104,9 @@ public static void tearDownCluster() {
@After
public void tearDown() {
// set back system out
// set back system out/err
System.setOut(OLD_OUT);
System.setErr(OLD_ERR);
}
@Test
@ -462,6 +465,45 @@ public void testCreateInvalidEntry() throws Exception {
assertEquals(-1, ToolRunner.run(admin, argv));
}
@Test
public void testNameserviceManager() throws Exception {
// Disable a name service and check if it's disabled
assertEquals(0, ToolRunner.run(admin,
new String[] {"-nameservice", "disable", "ns0"}));
stateStore.loadCache(DisabledNameserviceStoreImpl.class, true);
System.setOut(new PrintStream(out));
assertEquals(0, ToolRunner.run(admin,
new String[] {"-getDisabledNameservices"}));
assertTrue("ns0 should be reported: " + out,
out.toString().contains("ns0"));
// Enable a name service and check if it's there
assertEquals(0, ToolRunner.run(admin,
new String[] {"-nameservice", "enable", "ns0"}));
out.reset();
stateStore.loadCache(DisabledNameserviceStoreImpl.class, true);
assertEquals(0, ToolRunner.run(admin,
new String[] {"-getDisabledNameservices"}));
assertFalse("ns0 should not be reported: " + out,
out.toString().contains("ns0"));
// Wrong commands
System.setErr(new PrintStream(err));
assertEquals(-1, ToolRunner.run(admin,
new String[] {"-nameservice", "enable"}));
String msg = "Not enough parameters specificed for cmd -nameservice";
assertTrue("Got error: " + err.toString(),
err.toString().startsWith(msg));
err.reset();
assertEquals(-1, ToolRunner.run(admin,
new String[] {"-nameservice", "wrong", "ns0"}));
assertTrue("Got error: " + err.toString(),
err.toString().startsWith("nameservice: Unknown command: wrong"));
}
/**
* Wait for the Router transforming to expected state.
* @param expectedState Expected Router state.

View File

@ -41,6 +41,7 @@
import org.apache.hadoop.hdfs.server.federation.store.FederationStateStoreTestUtils;
import org.apache.hadoop.hdfs.server.federation.store.StateStoreService;
import org.apache.hadoop.hdfs.server.federation.store.records.BaseRecord;
import org.apache.hadoop.hdfs.server.federation.store.records.DisabledNameservice;
import org.apache.hadoop.hdfs.server.federation.store.records.MembershipState;
import org.apache.hadoop.hdfs.server.federation.store.records.MountTable;
import org.apache.hadoop.hdfs.server.federation.store.records.Query;
@ -139,6 +140,11 @@ private <T extends BaseRecord> T generateFakeRecord(Class<T> recordClass)
StateStoreVersion version = generateFakeRecord(StateStoreVersion.class);
routerState.setStateStoreVersion(version);
return (T) routerState;
} else if (recordClass == DisabledNameservice.class) {
return (T) DisabledNameservice.newInstance(generateRandomString());
} else if (recordClass == StateStoreVersion.class) {
return (T) StateStoreVersion.newInstance(
generateRandomLong(), generateRandomLong());
}
return null;
@ -186,6 +192,8 @@ private boolean validateRecord(
public static void removeAll(StateStoreDriver driver) throws IOException {
driver.removeAll(MembershipState.class);
driver.removeAll(MountTable.class);
driver.removeAll(RouterState.class);
driver.removeAll(DisabledNameservice.class);
}
public <T extends BaseRecord> void testInsert(
@ -290,7 +298,7 @@ public <T extends BaseRecord> void testPut(
// Verify no update occurred, all original records are unchanged
QueryResult<T> newRecords = driver.get(clazz);
assertTrue(newRecords.getRecords().size() == 10);
assertEquals(10, newRecords.getRecords().size());
assertEquals("A single entry was improperly updated in the store", 10,
countMatchingEntries(records.getRecords(), newRecords.getRecords()));
@ -300,10 +308,13 @@ public <T extends BaseRecord> void testPut(
// Verify that one entry no longer matches the original set
newRecords = driver.get(clazz);
assertEquals(10, newRecords.getRecords().size());
T record = records.getRecords().get(0);
if (record.hasOtherFields()) {
assertEquals(
"Record of type " + clazz + " not updated in the store", 9,
countMatchingEntries(records.getRecords(), newRecords.getRecords()));
}
}
private int countMatchingEntries(
Collection<? extends BaseRecord> committedList,
@ -379,6 +390,8 @@ public void testInsert(StateStoreDriver driver)
throws IllegalArgumentException, IllegalAccessException, IOException {
testInsert(driver, MembershipState.class);
testInsert(driver, MountTable.class);
testInsert(driver, RouterState.class);
testInsert(driver, DisabledNameservice.class);
}
public void testPut(StateStoreDriver driver)
@ -386,18 +399,24 @@ public void testPut(StateStoreDriver driver)
IOException, SecurityException {
testPut(driver, MembershipState.class);
testPut(driver, MountTable.class);
testPut(driver, RouterState.class);
testPut(driver, DisabledNameservice.class);
}
public void testRemove(StateStoreDriver driver)
throws IllegalArgumentException, IllegalAccessException, IOException {
testRemove(driver, MembershipState.class);
testRemove(driver, MountTable.class);
testRemove(driver, RouterState.class);
testRemove(driver, DisabledNameservice.class);
}
public void testFetchErrors(StateStoreDriver driver)
throws IllegalArgumentException, IllegalAccessException, IOException {
testFetchErrors(driver, MembershipState.class);
testFetchErrors(driver, MountTable.class);
testFetchErrors(driver, RouterState.class);
testFetchErrors(driver, DisabledNameservice.class);
}
public void testMetrics(StateStoreDriver driver)