HDFS-9848. Ozone: Add Ozone Client lib for volume handling. Contributed by Anu Engineer.
This commit is contained in:
parent
3481897bde
commit
0a43e272f1
|
@ -36,3 +36,6 @@
|
||||||
|
|
||||||
HDFS-9845. OzoneHandler : Support List and Info Volumes.
|
HDFS-9845. OzoneHandler : Support List and Info Volumes.
|
||||||
(Anu Engineer via cnauroth)
|
(Anu Engineer via cnauroth)
|
||||||
|
|
||||||
|
HDFS-9848. Ozone: Add Ozone Client lib for volume handling.
|
||||||
|
(Anu Engineer via cnauroth)
|
||||||
|
|
|
@ -18,11 +18,15 @@
|
||||||
package org.apache.hadoop.hdfs.server.datanode;
|
package org.apache.hadoop.hdfs.server.datanode;
|
||||||
|
|
||||||
import static com.sun.jersey.api.core.ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS;
|
import static com.sun.jersey.api.core.ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS;
|
||||||
|
import static com.sun.jersey.api.core.ResourceConfig.FEATURE_TRACE;
|
||||||
import static org.apache.hadoop.ozone.OzoneConfigKeys.DFS_STORAGE_HANDLER_TYPE_DEFAULT;
|
import static org.apache.hadoop.ozone.OzoneConfigKeys.DFS_STORAGE_HANDLER_TYPE_DEFAULT;
|
||||||
import static org.apache.hadoop.ozone.OzoneConfigKeys.DFS_STORAGE_HANDLER_TYPE_KEY;
|
import static org.apache.hadoop.ozone.OzoneConfigKeys.DFS_STORAGE_HANDLER_TYPE_KEY;
|
||||||
|
import static org.apache.hadoop.ozone.OzoneConfigKeys.DFS_OBJECTSTORE_TRACE_ENABLED_KEY;
|
||||||
|
import static org.apache.hadoop.ozone.OzoneConfigKeys.DFS_OBJECTSTORE_TRACE_ENABLED_DEFAULT;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.sun.jersey.api.container.ContainerFactory;
|
import com.sun.jersey.api.container.ContainerFactory;
|
||||||
import com.sun.jersey.api.core.ApplicationAdapter;
|
import com.sun.jersey.api.core.ApplicationAdapter;
|
||||||
|
@ -53,12 +57,14 @@ public final class ObjectStoreHandler {
|
||||||
public ObjectStoreHandler(Configuration conf) throws IOException {
|
public ObjectStoreHandler(Configuration conf) throws IOException {
|
||||||
String shType = conf.getTrimmed(DFS_STORAGE_HANDLER_TYPE_KEY,
|
String shType = conf.getTrimmed(DFS_STORAGE_HANDLER_TYPE_KEY,
|
||||||
DFS_STORAGE_HANDLER_TYPE_DEFAULT);
|
DFS_STORAGE_HANDLER_TYPE_DEFAULT);
|
||||||
|
boolean ozoneTrace = conf.getBoolean(DFS_OBJECTSTORE_TRACE_ENABLED_KEY,
|
||||||
|
DFS_OBJECTSTORE_TRACE_ENABLED_DEFAULT);
|
||||||
final StorageHandler storageHandler;
|
final StorageHandler storageHandler;
|
||||||
if ("distributed".equalsIgnoreCase(shType)) {
|
if ("distributed".equalsIgnoreCase(shType)) {
|
||||||
storageHandler = new DistributedStorageHandler();
|
storageHandler = new DistributedStorageHandler();
|
||||||
} else {
|
} else {
|
||||||
if ("local".equalsIgnoreCase(shType)) {
|
if ("local".equalsIgnoreCase(shType)) {
|
||||||
storageHandler = new LocalStorageHandler();
|
storageHandler = new LocalStorageHandler(conf);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
String.format("Unrecognized value for %s: %s",
|
String.format("Unrecognized value for %s: %s",
|
||||||
|
@ -67,9 +73,11 @@ public final class ObjectStoreHandler {
|
||||||
}
|
}
|
||||||
ApplicationAdapter aa =
|
ApplicationAdapter aa =
|
||||||
new ApplicationAdapter(new ObjectStoreApplication());
|
new ApplicationAdapter(new ObjectStoreApplication());
|
||||||
aa.setPropertiesAndFeatures(Collections.<String, Object>singletonMap(
|
Map<String, Object> settingsMap = new HashMap<>();
|
||||||
PROPERTY_CONTAINER_REQUEST_FILTERS,
|
settingsMap.put(PROPERTY_CONTAINER_REQUEST_FILTERS,
|
||||||
ServiceFilter.class.getCanonicalName()));
|
ServiceFilter.class.getCanonicalName());
|
||||||
|
settingsMap.put(FEATURE_TRACE, ozoneTrace);
|
||||||
|
aa.setPropertiesAndFeatures(settingsMap);
|
||||||
this.objectStoreJerseyContainer = ContainerFactory.createContainer(
|
this.objectStoreJerseyContainer = ContainerFactory.createContainer(
|
||||||
ObjectStoreJerseyContainer.class, aa);
|
ObjectStoreJerseyContainer.class, aa);
|
||||||
this.objectStoreJerseyContainer.setStorageHandler(storageHandler);
|
this.objectStoreJerseyContainer.setStorageHandler(storageHandler);
|
||||||
|
|
|
@ -34,6 +34,10 @@ public final class OzoneConfigKeys {
|
||||||
public static final String DFS_STORAGE_HANDLER_TYPE_KEY =
|
public static final String DFS_STORAGE_HANDLER_TYPE_KEY =
|
||||||
"dfs.storage.handler.type";
|
"dfs.storage.handler.type";
|
||||||
public static final String DFS_STORAGE_HANDLER_TYPE_DEFAULT = "distributed";
|
public static final String DFS_STORAGE_HANDLER_TYPE_DEFAULT = "distributed";
|
||||||
|
public static final String DFS_OBJECTSTORE_TRACE_ENABLED_KEY =
|
||||||
|
"dfs.objectstore.trace.enabled";
|
||||||
|
public static final boolean DFS_OBJECTSTORE_TRACE_ENABLED_DEFAULT = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* There is no need to instantiate this class.
|
* There is no need to instantiate this class.
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.apache.hadoop.ozone.web.exceptions.OzoneExceptionMapper;
|
||||||
import org.apache.hadoop.ozone.web.handlers.BucketHandler;
|
import org.apache.hadoop.ozone.web.handlers.BucketHandler;
|
||||||
import org.apache.hadoop.ozone.web.handlers.ServiceFilter;
|
import org.apache.hadoop.ozone.web.handlers.ServiceFilter;
|
||||||
import org.apache.hadoop.ozone.web.handlers.VolumeHandler;
|
import org.apache.hadoop.ozone.web.handlers.VolumeHandler;
|
||||||
|
import org.apache.hadoop.ozone.web.messages.StringMessageBodyWriter;
|
||||||
|
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -41,6 +42,7 @@ public class ObjectStoreApplication extends Application {
|
||||||
set.add(BucketHandler.class);
|
set.add(BucketHandler.class);
|
||||||
set.add(VolumeHandler.class);
|
set.add(VolumeHandler.class);
|
||||||
set.add(OzoneExceptionMapper.class);
|
set.add(OzoneExceptionMapper.class);
|
||||||
|
set.add(StringMessageBodyWriter.class);
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,544 @@
|
||||||
|
/*
|
||||||
|
* 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.ozone.web.client;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.web.exceptions.OzoneException;
|
||||||
|
import org.apache.hadoop.ozone.web.headers.Header;
|
||||||
|
import org.apache.hadoop.ozone.web.response.ListVolumes;
|
||||||
|
import org.apache.hadoop.ozone.web.response.VolumeInfo;
|
||||||
|
import org.apache.hadoop.ozone.web.utils.OzoneUtils;
|
||||||
|
import org.apache.hadoop.util.Time;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpDelete;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.HttpPut;
|
||||||
|
import org.apache.http.client.methods.HttpRequestBase;
|
||||||
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
|
import org.apache.http.impl.client.DefaultHttpClient;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import static java.net.HttpURLConnection.HTTP_CREATED;
|
||||||
|
import static java.net.HttpURLConnection.HTTP_OK;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ozone client that connects to an Ozone server. Please note that this class is
|
||||||
|
* not thread safe.
|
||||||
|
*/
|
||||||
|
public class OzoneClient implements Closeable {
|
||||||
|
private URI endPointURI;
|
||||||
|
private String userAuth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for OzoneClient.
|
||||||
|
*/
|
||||||
|
public OzoneClient() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for OzoneClient.
|
||||||
|
*/
|
||||||
|
public OzoneClient(String ozoneURI)
|
||||||
|
throws OzoneException, URISyntaxException {
|
||||||
|
setEndPoint(ozoneURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for OzoneClient.
|
||||||
|
*/
|
||||||
|
public OzoneClient(String ozoneURI, String userAuth)
|
||||||
|
throws OzoneException, URISyntaxException {
|
||||||
|
setEndPoint(ozoneURI);
|
||||||
|
setUserAuth(userAuth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the end Point.
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public URI getEndPointURI() {
|
||||||
|
return endPointURI;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the End Point info using an URI.
|
||||||
|
*
|
||||||
|
* @param endPointURI - URI
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
public void setEndPointURI(URI endPointURI) throws OzoneException {
|
||||||
|
if ((endPointURI == null) || (endPointURI.toString().isEmpty())) {
|
||||||
|
throw new OzoneClientException("Invalid ozone URI");
|
||||||
|
}
|
||||||
|
this.endPointURI = endPointURI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set endPoint.
|
||||||
|
*
|
||||||
|
* @param clusterFQDN - cluster FQDN.
|
||||||
|
*/
|
||||||
|
public void setEndPoint(String clusterFQDN) throws
|
||||||
|
OzoneException, URISyntaxException {
|
||||||
|
setEndPointURI(new URI(clusterFQDN));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user Auth String.
|
||||||
|
*
|
||||||
|
* @return - User Auth String
|
||||||
|
*/
|
||||||
|
public String getUserAuth() {
|
||||||
|
return this.userAuth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set User Auth.
|
||||||
|
*
|
||||||
|
* @param userAuth - User Auth String
|
||||||
|
*/
|
||||||
|
public void setUserAuth(String userAuth) {
|
||||||
|
this.userAuth = userAuth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create volume.
|
||||||
|
*
|
||||||
|
* @param volumeName - volume name 3 - 63 chars, small letters.
|
||||||
|
* @param onBehalfOf - The user on behalf we are making the call for
|
||||||
|
* @param quota - Quota's are specified in a specific format. it is
|
||||||
|
* integer(MB|GB|TB), for example 100TB.
|
||||||
|
* @throws OzoneClientException
|
||||||
|
*/
|
||||||
|
public OzoneVolume createVolume(String volumeName, String onBehalfOf,
|
||||||
|
String quota) throws OzoneException {
|
||||||
|
try {
|
||||||
|
DefaultHttpClient httpClient = new DefaultHttpClient();
|
||||||
|
OzoneUtils.verifyBucketName(volumeName);
|
||||||
|
|
||||||
|
URIBuilder builder = new URIBuilder(endPointURI);
|
||||||
|
builder.setPath("/" + volumeName);
|
||||||
|
if (quota != null) {
|
||||||
|
builder.setParameter(Header.OZONE_QUOTA_QUERY_TAG, quota);
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpPost httppost = getHttpPost(onBehalfOf, builder.build().toString());
|
||||||
|
executeCreateVolume(httppost, httpClient);
|
||||||
|
return getVolume(volumeName);
|
||||||
|
} catch (IOException | URISyntaxException | IllegalArgumentException ex) {
|
||||||
|
throw new OzoneClientException(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about an existing Volume. if the Volume does not exist,
|
||||||
|
* or if the user does not have access rights OzoneException is thrown
|
||||||
|
*
|
||||||
|
* @param volumeName - volume name 3 - 63 chars, small letters.
|
||||||
|
* @return OzoneVolume Ozone Client Volume Class.
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
public OzoneVolume getVolume(String volumeName) throws OzoneException {
|
||||||
|
try {
|
||||||
|
DefaultHttpClient httpClient = new DefaultHttpClient();
|
||||||
|
|
||||||
|
OzoneUtils.verifyBucketName(volumeName);
|
||||||
|
URIBuilder builder = new URIBuilder(endPointURI);
|
||||||
|
builder.setPath("/" + volumeName)
|
||||||
|
.setParameter(Header.OZONE_LIST_QUERY_TAG,
|
||||||
|
Header.OZONE_LIST_QUERY_VOLUME)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpGet httpget = getHttpGet(builder.toString());
|
||||||
|
return executeInfoVolume(httpget, httpClient);
|
||||||
|
|
||||||
|
} catch (IOException | URISyntaxException | IllegalArgumentException ex) {
|
||||||
|
throw new OzoneClientException(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all the volumes owned by the user or Owned by the user specified in
|
||||||
|
* the behalf of string.
|
||||||
|
*
|
||||||
|
* @param onBehalfOf - User Name of the user if it is not the caller. for
|
||||||
|
* example, an admin wants to list some other users
|
||||||
|
* volumes.
|
||||||
|
* @return List of Volumes
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
public List<OzoneVolume> listVolumes(String onBehalfOf)
|
||||||
|
throws OzoneException {
|
||||||
|
try {
|
||||||
|
DefaultHttpClient httpClient = new DefaultHttpClient();
|
||||||
|
|
||||||
|
URIBuilder builder = new URIBuilder(endPointURI);
|
||||||
|
builder.setPath("/").build();
|
||||||
|
|
||||||
|
HttpGet httpget = getHttpGet(builder.toString());
|
||||||
|
if (onBehalfOf != null) {
|
||||||
|
httpget.addHeader(Header.OZONE_USER, onBehalfOf);
|
||||||
|
}
|
||||||
|
return executeListVolume(httpget, httpClient);
|
||||||
|
|
||||||
|
} catch (IOException | URISyntaxException ex) {
|
||||||
|
throw new OzoneClientException(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete a given volume.
|
||||||
|
*
|
||||||
|
* @param volumeName - volume to be deleted.
|
||||||
|
* @throws OzoneException - Ozone Exception
|
||||||
|
*/
|
||||||
|
public void deleteVolume(String volumeName) throws OzoneException {
|
||||||
|
try {
|
||||||
|
DefaultHttpClient httpClient = new DefaultHttpClient();
|
||||||
|
|
||||||
|
OzoneUtils.verifyBucketName(volumeName);
|
||||||
|
URIBuilder builder = new URIBuilder(endPointURI);
|
||||||
|
builder.setPath("/" + volumeName).build();
|
||||||
|
|
||||||
|
HttpDelete httpdelete = getHttpDelete(builder.toString());
|
||||||
|
executeDeleteVolume(httpdelete, httpClient);
|
||||||
|
} catch (IOException | URISyntaxException | IllegalArgumentException ex) {
|
||||||
|
throw new OzoneClientException(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Volume Owner.
|
||||||
|
*
|
||||||
|
* @param volumeName - Volume Name
|
||||||
|
* @param newOwner - New Owner Name
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
public void setVolumeOwner(String volumeName, String newOwner)
|
||||||
|
throws OzoneException {
|
||||||
|
|
||||||
|
if (newOwner == null || newOwner.isEmpty()) {
|
||||||
|
throw new OzoneClientException("Invalid new owner name");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
DefaultHttpClient httpClient = new DefaultHttpClient();
|
||||||
|
|
||||||
|
OzoneUtils.verifyBucketName(volumeName);
|
||||||
|
URIBuilder builder = new URIBuilder(endPointURI);
|
||||||
|
builder.setPath("/" + volumeName).build();
|
||||||
|
|
||||||
|
HttpPut putRequest = getHttpPut(builder.toString());
|
||||||
|
putRequest.addHeader(Header.OZONE_USER, newOwner);
|
||||||
|
executePutVolume(putRequest, httpClient);
|
||||||
|
|
||||||
|
} catch (URISyntaxException | IllegalArgumentException | IOException ex) {
|
||||||
|
throw new OzoneClientException(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Volume Quota. Quota's are specified in a specific format. it is
|
||||||
|
* <integer>|(MB|GB|TB. for example 100TB.
|
||||||
|
* <p>
|
||||||
|
* To Remove a quota you can specify Header.OZONE_QUOTA_REMOVE
|
||||||
|
*
|
||||||
|
* @param volumeName - volume name
|
||||||
|
* @param quota - Quota String or Header.OZONE_QUOTA_REMOVE
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
public void setVolumeQuota(String volumeName, String quota)
|
||||||
|
throws OzoneException {
|
||||||
|
if (quota == null || quota.isEmpty()) {
|
||||||
|
throw new OzoneClientException("Invalid quota");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
DefaultHttpClient httpClient = new DefaultHttpClient();
|
||||||
|
|
||||||
|
OzoneUtils.verifyBucketName(volumeName);
|
||||||
|
URIBuilder builder = new URIBuilder(endPointURI);
|
||||||
|
builder.setPath("/" + volumeName)
|
||||||
|
.setParameter(Header.OZONE_QUOTA_QUERY_TAG, quota)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpPut putRequest = getHttpPut(builder.toString());
|
||||||
|
executePutVolume(putRequest, httpClient);
|
||||||
|
|
||||||
|
} catch (URISyntaxException | IllegalArgumentException | IOException ex) {
|
||||||
|
throw new OzoneClientException(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the create Volume request to the server.
|
||||||
|
*
|
||||||
|
* @param httppost - http post class
|
||||||
|
* @param httpClient - httpClient
|
||||||
|
* @throws IOException -
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
private void executeCreateVolume(HttpPost httppost,
|
||||||
|
DefaultHttpClient httpClient)
|
||||||
|
throws IOException, OzoneException {
|
||||||
|
HttpEntity entity = null;
|
||||||
|
try {
|
||||||
|
HttpResponse response = httpClient.execute(httppost);
|
||||||
|
int errorCode = response.getStatusLine().getStatusCode();
|
||||||
|
entity = response.getEntity();
|
||||||
|
|
||||||
|
if ((errorCode == HTTP_OK) || (errorCode == HTTP_CREATED)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity != null) {
|
||||||
|
throw OzoneException.parse(EntityUtils.toString(entity));
|
||||||
|
} else {
|
||||||
|
throw new OzoneClientException("Unexpected null in http payload");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (entity != null) {
|
||||||
|
EntityUtils.consume(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the create Volume request to the server.
|
||||||
|
*
|
||||||
|
* @param httpGet - httpGet
|
||||||
|
* @return OzoneVolume
|
||||||
|
* @throws IOException -
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
private OzoneVolume executeInfoVolume(HttpGet httpGet,
|
||||||
|
DefaultHttpClient httpClient)
|
||||||
|
throws IOException, OzoneException {
|
||||||
|
HttpEntity entity = null;
|
||||||
|
try {
|
||||||
|
HttpResponse response = httpClient.execute(httpGet);
|
||||||
|
int errorCode = response.getStatusLine().getStatusCode();
|
||||||
|
|
||||||
|
entity = response.getEntity();
|
||||||
|
if (entity == null) {
|
||||||
|
throw new OzoneClientException("Unexpected null in http payload");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorCode == HTTP_OK) {
|
||||||
|
OzoneVolume volume = new OzoneVolume(this);
|
||||||
|
volume.setVolumeInfo(EntityUtils.toString(entity));
|
||||||
|
return volume;
|
||||||
|
} else {
|
||||||
|
throw OzoneException.parse(EntityUtils.toString(entity));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (entity != null) {
|
||||||
|
EntityUtils.consumeQuietly(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends update volume requests to the server.
|
||||||
|
*
|
||||||
|
* @param putRequest http request
|
||||||
|
* @throws IOException
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
private void executePutVolume(HttpPut putRequest,
|
||||||
|
DefaultHttpClient httpClient)
|
||||||
|
throws IOException, OzoneException {
|
||||||
|
HttpEntity entity = null;
|
||||||
|
try {
|
||||||
|
HttpResponse response = httpClient.execute(putRequest);
|
||||||
|
int errorCode = response.getStatusLine().getStatusCode();
|
||||||
|
entity = response.getEntity();
|
||||||
|
if (errorCode != HTTP_OK) {
|
||||||
|
throw OzoneException.parse(EntityUtils.toString(entity));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (entity != null) {
|
||||||
|
EntityUtils.consume(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List Volumes.
|
||||||
|
*
|
||||||
|
* @param httpGet - httpGet
|
||||||
|
* @return OzoneVolume
|
||||||
|
* @throws IOException -
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
private List<OzoneVolume> executeListVolume(HttpGet httpGet,
|
||||||
|
DefaultHttpClient httpClient)
|
||||||
|
throws IOException, OzoneException {
|
||||||
|
HttpEntity entity = null;
|
||||||
|
List<OzoneVolume> volList = new LinkedList<>();
|
||||||
|
try {
|
||||||
|
HttpResponse response = httpClient.execute(httpGet);
|
||||||
|
int errorCode = response.getStatusLine().getStatusCode();
|
||||||
|
entity = response.getEntity();
|
||||||
|
|
||||||
|
if (entity == null) {
|
||||||
|
throw new OzoneClientException("Unexpected null in http payload");
|
||||||
|
}
|
||||||
|
|
||||||
|
String temp = EntityUtils.toString(entity);
|
||||||
|
if (errorCode == HTTP_OK) {
|
||||||
|
ListVolumes listVolumes =
|
||||||
|
ListVolumes.parse(temp);
|
||||||
|
|
||||||
|
for (VolumeInfo info : listVolumes.getVolumes()) {
|
||||||
|
volList.add(new OzoneVolume(info, this));
|
||||||
|
}
|
||||||
|
return volList;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw OzoneException.parse(EntityUtils.toString(entity));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (entity != null) {
|
||||||
|
EntityUtils.consumeQuietly(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete Volume.
|
||||||
|
*
|
||||||
|
* @param httpDelete - Http Delete Request
|
||||||
|
* @throws IOException
|
||||||
|
* @throws OzoneException
|
||||||
|
*/
|
||||||
|
private void executeDeleteVolume(HttpDelete httpDelete,
|
||||||
|
DefaultHttpClient httpClient)
|
||||||
|
throws IOException, OzoneException {
|
||||||
|
HttpEntity entity = null;
|
||||||
|
try {
|
||||||
|
HttpResponse response = httpClient.execute(httpDelete);
|
||||||
|
int errorCode = response.getStatusLine().getStatusCode();
|
||||||
|
entity = response.getEntity();
|
||||||
|
|
||||||
|
if (errorCode != HTTP_OK) {
|
||||||
|
throw OzoneException.parse(EntityUtils.toString(entity));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (entity != null) {
|
||||||
|
EntityUtils.consumeQuietly(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a standard HttpPost Object to use for ozone post requests.
|
||||||
|
*
|
||||||
|
* @param onBehalfOf - If the use is being made on behalf of user, that user
|
||||||
|
* @param uriString - UriString
|
||||||
|
* @return HttpPost
|
||||||
|
*/
|
||||||
|
public HttpPost getHttpPost(String onBehalfOf, String uriString) {
|
||||||
|
HttpPost httppost = new HttpPost(uriString);
|
||||||
|
addOzoneHeaders(httppost);
|
||||||
|
if (onBehalfOf != null) {
|
||||||
|
httppost.addHeader(Header.OZONE_USER, onBehalfOf);
|
||||||
|
}
|
||||||
|
return httppost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a standard HttpGet Object to use for ozone Get requests.
|
||||||
|
*
|
||||||
|
* @param uriString - The full Uri String
|
||||||
|
* @return HttpGet
|
||||||
|
*/
|
||||||
|
public HttpGet getHttpGet(String uriString) {
|
||||||
|
HttpGet httpget = new HttpGet(uriString);
|
||||||
|
addOzoneHeaders(httpget);
|
||||||
|
return httpget;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns httpDelete.
|
||||||
|
*
|
||||||
|
* @param uriString - uri
|
||||||
|
* @return HttpDelete
|
||||||
|
*/
|
||||||
|
public HttpDelete getHttpDelete(String uriString) {
|
||||||
|
HttpDelete httpDel = new HttpDelete(uriString);
|
||||||
|
addOzoneHeaders(httpDel);
|
||||||
|
return httpDel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns an HttpPut Object.
|
||||||
|
*
|
||||||
|
* @param uriString - Uri
|
||||||
|
* @return HttpPut
|
||||||
|
*/
|
||||||
|
public HttpPut getHttpPut(String uriString) {
|
||||||
|
HttpPut httpPut = new HttpPut(uriString);
|
||||||
|
addOzoneHeaders(httpPut);
|
||||||
|
return httpPut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Ozone Headers.
|
||||||
|
*
|
||||||
|
* @param httpRequest - Http Request
|
||||||
|
*/
|
||||||
|
private void addOzoneHeaders(HttpRequestBase httpRequest) {
|
||||||
|
SimpleDateFormat format =
|
||||||
|
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ZZZ", Locale.US);
|
||||||
|
|
||||||
|
httpRequest.addHeader(Header.OZONE_VERSION_HEADER,
|
||||||
|
Header.OZONE_V1_VERSION_HEADER);
|
||||||
|
httpRequest.addHeader(HttpHeaders.DATE,
|
||||||
|
format.format(new Date(Time.monotonicNow())));
|
||||||
|
if (getUserAuth() != null) {
|
||||||
|
httpRequest.addHeader(HttpHeaders.AUTHORIZATION,
|
||||||
|
Header.OZONE_SIMPLE_AUTHENTICATION_SCHEME + " " +
|
||||||
|
getUserAuth());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes this stream and releases any system resources associated with it. If
|
||||||
|
* the stream is already closed then invoking this method has no effect.
|
||||||
|
*
|
||||||
|
* @throws IOException if an I/O error occurs
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
// TODO : Currently we create a new HTTP client. We should switch
|
||||||
|
// This to a Pool and cleanup the pool here.
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* 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.ozone.web.client;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.web.exceptions.OzoneException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This exception is thrown by the Ozone Clients.
|
||||||
|
*/
|
||||||
|
public class OzoneClientException extends OzoneException {
|
||||||
|
/**
|
||||||
|
* Constructor that allows the shortMessage.
|
||||||
|
*
|
||||||
|
* @param shortMessage Short Message
|
||||||
|
*/
|
||||||
|
public OzoneClientException(String shortMessage) {
|
||||||
|
super(0, shortMessage, shortMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor that allows the shortMessage and a longer message.
|
||||||
|
*
|
||||||
|
* @param shortMessage Short Message
|
||||||
|
* @param message long error message
|
||||||
|
*/
|
||||||
|
public OzoneClientException(String shortMessage, String message) {
|
||||||
|
super(0, shortMessage, message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* 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.ozone.web.client;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.web.request.OzoneQuota;
|
||||||
|
import org.apache.hadoop.ozone.web.response.VolumeInfo;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ozone Volume Class.
|
||||||
|
*/
|
||||||
|
public class OzoneVolume {
|
||||||
|
private VolumeInfo volumeInfo;
|
||||||
|
private Map<String, String> headerMap;
|
||||||
|
private final OzoneClient client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for OzoneVolume.
|
||||||
|
*/
|
||||||
|
public OzoneVolume(OzoneClient client) {
|
||||||
|
this.client = client;
|
||||||
|
this.headerMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for OzoneVolume.
|
||||||
|
*
|
||||||
|
* @param volInfo - volume Info.
|
||||||
|
* @param client Client
|
||||||
|
*/
|
||||||
|
public OzoneVolume(VolumeInfo volInfo, OzoneClient client) {
|
||||||
|
this.volumeInfo = volInfo;
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJsonString() throws IOException {
|
||||||
|
return volumeInfo.toJsonString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the Volume Info.
|
||||||
|
*
|
||||||
|
* @param volInfoString - Volume Info String
|
||||||
|
*/
|
||||||
|
public void setVolumeInfo(String volInfoString) throws IOException {
|
||||||
|
this.volumeInfo = VolumeInfo.parse(volInfoString);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns volume Name.
|
||||||
|
*
|
||||||
|
* @return Volume Name.
|
||||||
|
*/
|
||||||
|
public String getVolumeName() {
|
||||||
|
return this.volumeInfo.getVolumeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get created by.
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getCreatedby() {
|
||||||
|
return this.volumeInfo.getCreatedBy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the Owner name.
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getOwnerName() {
|
||||||
|
return this.volumeInfo.getOwner().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Quota Info.
|
||||||
|
*
|
||||||
|
* @return Quota
|
||||||
|
*/
|
||||||
|
public OzoneQuota getQuota() {
|
||||||
|
return volumeInfo.getQuota();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a Http header from the Last Volume related call.
|
||||||
|
*
|
||||||
|
* @param headerName - Name of the header
|
||||||
|
* @return - Header Value
|
||||||
|
*/
|
||||||
|
public String getHeader(String headerName) {
|
||||||
|
return headerMap.get(headerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Client, this is used by Bucket and Key Classes.
|
||||||
|
*
|
||||||
|
* @return - Ozone Client
|
||||||
|
*/
|
||||||
|
OzoneClient getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ozone client library is a java client for the Ozone
|
||||||
|
* Object Store.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.web.client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
This library is a simple Ozone REST Library.
|
||||||
|
|
||||||
|
This library is a very *minimal* client written for tests and
|
||||||
|
command line utils that work against Ozone. It does not have
|
||||||
|
things like thread-pools and support for extended security models yet.
|
||||||
|
|
||||||
|
OzoneClients return OzoneVolumes and OzoneVolumes return OzoneBuckets.
|
||||||
|
**/
|
|
@ -46,6 +46,16 @@ public class OzoneException extends Exception {
|
||||||
@JsonProperty("hostName")
|
@JsonProperty("hostName")
|
||||||
private String hostID;
|
private String hostID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new exception with {@code null} as its detail message. The
|
||||||
|
* cause is not initialized, and may subsequently be initialized by a call
|
||||||
|
* to {@link #initCause}.
|
||||||
|
*
|
||||||
|
* This constructor is needed by Json Serializer.
|
||||||
|
*/
|
||||||
|
public OzoneException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor that allows a shortMessage and exception.
|
* Constructor that allows a shortMessage and exception.
|
||||||
|
|
|
@ -181,7 +181,7 @@ public abstract class BucketProcessTemplate {
|
||||||
*
|
*
|
||||||
* @throws OzoneException
|
* @throws OzoneException
|
||||||
*/
|
*/
|
||||||
List<String> getAcls(BucketArgs args, String tag) throws OzoneException {
|
List<String> getAcls(BucketArgs args, String tag) {
|
||||||
List<String> aclStrings =
|
List<String> aclStrings =
|
||||||
args.getHeaders().getRequestHeader(Header.OZONE_ACLS);
|
args.getHeaders().getRequestHeader(Header.OZONE_ACLS);
|
||||||
List<String> filteredSet = null;
|
List<String> filteredSet = null;
|
||||||
|
@ -242,7 +242,7 @@ public abstract class BucketProcessTemplate {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<String> storageClassString =
|
List<String> storageClassString =
|
||||||
args.getHeaders().getRequestHeader(Header.OZONE_STORAGE_CLASS);
|
args.getHeaders().getRequestHeader(Header.OZONE_STORAGE_TYPE);
|
||||||
if (storageClassString == null) {
|
if (storageClassString == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
package org.apache.hadoop.ozone.web.handlers;
|
package org.apache.hadoop.ozone.web.handlers;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.ozone.OzoneConfiguration;
|
||||||
import org.apache.hadoop.ozone.web.interfaces.StorageHandler;
|
import org.apache.hadoop.ozone.web.interfaces.StorageHandler;
|
||||||
import org.apache.hadoop.ozone.web.localstorage.LocalStorageHandler;
|
import org.apache.hadoop.ozone.web.localstorage.LocalStorageHandler;
|
||||||
|
|
||||||
|
@ -44,7 +46,8 @@ public final class StorageHandlerBuilder {
|
||||||
return storageHandler;
|
return storageHandler;
|
||||||
} else {
|
} else {
|
||||||
// This only happens while using mvn jetty:run for testing.
|
// This only happens while using mvn jetty:run for testing.
|
||||||
return new LocalStorageHandler();
|
Configuration conf = new OzoneConfiguration();
|
||||||
|
return new LocalStorageHandler(conf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ public final class Header {
|
||||||
public static final String OZONE_REQUEST_ID = "x-ozone-request-id";
|
public static final String OZONE_REQUEST_ID = "x-ozone-request-id";
|
||||||
public static final String OZONE_SERVER_NAME = "x-ozone-server-name";
|
public static final String OZONE_SERVER_NAME = "x-ozone-server-name";
|
||||||
|
|
||||||
public static final String OZONE_STORAGE_CLASS = "x-ozone-storage-type";
|
public static final String OZONE_STORAGE_TYPE = "x-ozone-storage-type";
|
||||||
|
|
||||||
public static final String OZONE_BUCKET_VERSIONING =
|
public static final String OZONE_BUCKET_VERSIONING =
|
||||||
"x-ozone-bucket-versioning";
|
"x-ozone-bucket-versioning";
|
||||||
|
@ -54,6 +54,10 @@ public final class Header {
|
||||||
public static final String OZONE_ACL_ADD = "ADD";
|
public static final String OZONE_ACL_ADD = "ADD";
|
||||||
public static final String OZONE_ACL_REMOVE = "REMOVE";
|
public static final String OZONE_ACL_REMOVE = "REMOVE";
|
||||||
|
|
||||||
|
public static final String OZONE_LIST_QUERY_TAG ="info";
|
||||||
|
public static final String OZONE_QUOTA_QUERY_TAG ="quota";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Header() {
|
private Header() {
|
||||||
// Never constructed.
|
// Never constructed.
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.apache.hadoop.ozone.web.localstorage;
|
package org.apache.hadoop.ozone.web.localstorage;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.ozone.web.exceptions.OzoneException;
|
import org.apache.hadoop.ozone.web.exceptions.OzoneException;
|
||||||
import org.apache.hadoop.ozone.web.handlers.BucketArgs;
|
import org.apache.hadoop.ozone.web.handlers.BucketArgs;
|
||||||
import org.apache.hadoop.ozone.web.handlers.UserArgs;
|
import org.apache.hadoop.ozone.web.handlers.UserArgs;
|
||||||
|
@ -40,10 +41,12 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
public class LocalStorageHandler implements StorageHandler {
|
public class LocalStorageHandler implements StorageHandler {
|
||||||
|
private final Configuration conf;
|
||||||
/**
|
/**
|
||||||
* Constructs LocalStorageHandler.
|
* Constructs LocalStorageHandler.
|
||||||
*/
|
*/
|
||||||
public LocalStorageHandler() {
|
public LocalStorageHandler(Configuration conf) {
|
||||||
|
this.conf = conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +58,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void createVolume(VolumeArgs args) throws IOException, OzoneException {
|
public void createVolume(VolumeArgs args) throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
oz.createVolume(args);
|
oz.createVolume(args);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -70,7 +74,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
@Override
|
@Override
|
||||||
public void setVolumeOwner(VolumeArgs args)
|
public void setVolumeOwner(VolumeArgs args)
|
||||||
throws IOException, OzoneException {
|
throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
oz.setVolumeProperty(args, OzoneMetadataManager.VolumeProperty.OWNER);
|
oz.setVolumeProperty(args, OzoneMetadataManager.VolumeProperty.OWNER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +90,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
@Override
|
@Override
|
||||||
public void setVolumeQuota(VolumeArgs args, boolean remove)
|
public void setVolumeQuota(VolumeArgs args, boolean remove)
|
||||||
throws IOException, OzoneException {
|
throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
|
|
||||||
if(remove) {
|
if(remove) {
|
||||||
OzoneQuota quota = new OzoneQuota();
|
OzoneQuota quota = new OzoneQuota();
|
||||||
|
@ -109,7 +115,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
@Override
|
@Override
|
||||||
public boolean checkVolumeAccess(VolumeArgs args)
|
public boolean checkVolumeAccess(VolumeArgs args)
|
||||||
throws IOException, OzoneException {
|
throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
return oz.checkVolumeAccess(args);
|
return oz.checkVolumeAccess(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +133,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
@Override
|
@Override
|
||||||
public VolumeInfo getVolumeInfo(VolumeArgs args)
|
public VolumeInfo getVolumeInfo(VolumeArgs args)
|
||||||
throws IOException, OzoneException {
|
throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
return oz.getVolumeInfo(args);
|
return oz.getVolumeInfo(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +148,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void deleteVolume(VolumeArgs args) throws IOException, OzoneException {
|
public void deleteVolume(VolumeArgs args) throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
oz.deleteVolume(args);
|
oz.deleteVolume(args);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -157,7 +166,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
@Override
|
@Override
|
||||||
public ListVolumes listVolumes(UserArgs args)
|
public ListVolumes listVolumes(UserArgs args)
|
||||||
throws IOException, OzoneException {
|
throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
return oz.listVolumes(args);
|
return oz.listVolumes(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +194,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void createBucket(BucketArgs args) throws IOException, OzoneException {
|
public void createBucket(BucketArgs args) throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
oz.createBucket(args);
|
oz.createBucket(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +209,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
@Override
|
@Override
|
||||||
public void setBucketAcls(BucketArgs args)
|
public void setBucketAcls(BucketArgs args)
|
||||||
throws IOException, OzoneException {
|
throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
oz.setBucketProperty(args, OzoneMetadataManager.BucketProperty.ACLS);
|
oz.setBucketProperty(args, OzoneMetadataManager.BucketProperty.ACLS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +224,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
@Override
|
@Override
|
||||||
public void setBucketVersioning(BucketArgs args)
|
public void setBucketVersioning(BucketArgs args)
|
||||||
throws IOException, OzoneException {
|
throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
oz.setBucketProperty(args, OzoneMetadataManager.BucketProperty.VERSIONING);
|
oz.setBucketProperty(args, OzoneMetadataManager.BucketProperty.VERSIONING);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -227,7 +240,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
@Override
|
@Override
|
||||||
public void setBucketStorageClass(BucketArgs args)
|
public void setBucketStorageClass(BucketArgs args)
|
||||||
throws IOException, OzoneException {
|
throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
oz.setBucketProperty(args, OzoneMetadataManager.BucketProperty.STORAGETYPE);
|
oz.setBucketProperty(args, OzoneMetadataManager.BucketProperty.STORAGETYPE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -241,7 +255,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void deleteBucket(BucketArgs args) throws IOException, OzoneException {
|
public void deleteBucket(BucketArgs args) throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
oz.deleteBucket(args);
|
oz.deleteBucket(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +272,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
@Override
|
@Override
|
||||||
public ListBuckets listBuckets(VolumeArgs args)
|
public ListBuckets listBuckets(VolumeArgs args)
|
||||||
throws IOException, OzoneException {
|
throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
return oz.listBuckets(args);
|
return oz.listBuckets(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +289,8 @@ public class LocalStorageHandler implements StorageHandler {
|
||||||
@Override
|
@Override
|
||||||
public BucketInfo getBucketInfo(BucketArgs args)
|
public BucketInfo getBucketInfo(BucketArgs args)
|
||||||
throws IOException, OzoneException {
|
throws IOException, OzoneException {
|
||||||
OzoneMetadataManager oz = OzoneMetadataManager.getOzoneMetadataManager();
|
OzoneMetadataManager oz =
|
||||||
|
OzoneMetadataManager.getOzoneMetadataManager(conf);
|
||||||
return oz.getBucketInfo(args);
|
return oz.getBucketInfo(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@ package org.apache.hadoop.ozone.web.localstorage;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.ozone.OzoneConfigKeys;
|
import org.apache.hadoop.ozone.OzoneConfigKeys;
|
||||||
import org.apache.hadoop.ozone.OzoneConfiguration;
|
|
||||||
import org.apache.hadoop.ozone.web.exceptions.ErrorTable;
|
import org.apache.hadoop.ozone.web.exceptions.ErrorTable;
|
||||||
import org.apache.hadoop.ozone.web.exceptions.OzoneException;
|
import org.apache.hadoop.ozone.web.exceptions.OzoneException;
|
||||||
import org.apache.hadoop.ozone.web.handlers.BucketArgs;
|
import org.apache.hadoop.ozone.web.handlers.BucketArgs;
|
||||||
|
@ -123,11 +123,9 @@ public final class OzoneMetadataManager {
|
||||||
/**
|
/**
|
||||||
* Constructs OzoneMetadataManager.
|
* Constructs OzoneMetadataManager.
|
||||||
*/
|
*/
|
||||||
private OzoneMetadataManager() {
|
private OzoneMetadataManager(Configuration conf) {
|
||||||
|
|
||||||
lock = new ReentrantReadWriteLock();
|
lock = new ReentrantReadWriteLock();
|
||||||
OzoneConfiguration conf = new OzoneConfiguration();
|
|
||||||
|
|
||||||
String storageRoot =
|
String storageRoot =
|
||||||
conf.getTrimmed(OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT,
|
conf.getTrimmed(OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT,
|
||||||
OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT_DEFAULT);
|
OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT_DEFAULT);
|
||||||
|
@ -151,9 +149,10 @@ public final class OzoneMetadataManager {
|
||||||
*
|
*
|
||||||
* @return OzoneMetadataManager
|
* @return OzoneMetadataManager
|
||||||
*/
|
*/
|
||||||
public static synchronized OzoneMetadataManager getOzoneMetadataManager() {
|
public static synchronized OzoneMetadataManager
|
||||||
|
getOzoneMetadataManager(Configuration conf) {
|
||||||
if (bm == null) {
|
if (bm == null) {
|
||||||
bm = new OzoneMetadataManager();
|
bm = new OzoneMetadataManager(conf);
|
||||||
}
|
}
|
||||||
return bm;
|
return bm;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* 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.ozone.web.messages;
|
||||||
|
|
||||||
|
import org.apache.hadoop.io.IOUtils;
|
||||||
|
import org.apache.hadoop.ozone.web.utils.OzoneUtils;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
|
import javax.ws.rs.ext.MessageBodyWriter;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes outbound HTTP response strings. We use this rather than the built-in
|
||||||
|
* writer so that we can determine content length from the string length instead
|
||||||
|
* of possibly falling back to a chunked response.
|
||||||
|
*/
|
||||||
|
public final class StringMessageBodyWriter implements
|
||||||
|
MessageBodyWriter<String> {
|
||||||
|
private static final int CHUNK_SIZE = 8192;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSize(String str, Class<?> type, Type genericType,
|
||||||
|
Annotation[] annotations, MediaType mediaType) {
|
||||||
|
return str.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWriteable(Class<?> type, Type genericType,
|
||||||
|
Annotation[] annotations, MediaType mediaType) {
|
||||||
|
return String.class.isAssignableFrom(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(String str, Class<?> type, Type genericType,
|
||||||
|
Annotation[] annotations, MediaType mediaType,
|
||||||
|
MultivaluedMap<String, Object> httpHeaders,
|
||||||
|
OutputStream out) throws IOException {
|
||||||
|
IOUtils.copyBytes(new ByteArrayInputStream(
|
||||||
|
str.getBytes(OzoneUtils.ENCODING)), out, CHUNK_SIZE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ import javax.ws.rs.core.Response;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -44,6 +45,8 @@ import java.util.UUID;
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
public final class OzoneUtils {
|
public final class OzoneUtils {
|
||||||
|
|
||||||
|
public static final Charset ENCODING = Charset.forName("UTF-8");
|
||||||
|
|
||||||
private OzoneUtils() {
|
private OzoneUtils() {
|
||||||
// Never constructed
|
// Never constructed
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.impl.client.DefaultHttpClient;
|
import org.apache.http.impl.client.DefaultHttpClient;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -64,13 +66,15 @@ public class TestOzoneVolumes {
|
||||||
OzoneConfiguration conf = new OzoneConfiguration();
|
OzoneConfiguration conf = new OzoneConfiguration();
|
||||||
|
|
||||||
URL p = conf.getClass().getResource("");
|
URL p = conf.getClass().getResource("");
|
||||||
String path = p.getPath();
|
String path = p.getPath().concat(TestOzoneVolumes.class.getSimpleName());
|
||||||
path += conf.getTrimmed(OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT,
|
path += conf.getTrimmed(OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT,
|
||||||
OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT_DEFAULT);
|
OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT_DEFAULT);
|
||||||
|
|
||||||
conf.set(OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT, path);
|
conf.set(OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT, path);
|
||||||
conf.setBoolean(OzoneConfigKeys.DFS_OBJECTSTORE_ENABLED_KEY, true);
|
conf.setBoolean(OzoneConfigKeys.DFS_OBJECTSTORE_ENABLED_KEY, true);
|
||||||
conf.set(OzoneConfigKeys.DFS_STORAGE_HANDLER_TYPE_KEY, "local");
|
conf.set(OzoneConfigKeys.DFS_STORAGE_HANDLER_TYPE_KEY, "local");
|
||||||
|
conf.setBoolean(OzoneConfigKeys.DFS_OBJECTSTORE_TRACE_ENABLED_KEY, true);
|
||||||
|
Logger.getLogger("log4j.logger.org.apache.http").setLevel(Level.DEBUG);
|
||||||
|
|
||||||
cluster = new MiniDFSCluster.Builder(conf).build();
|
cluster = new MiniDFSCluster.Builder(conf).build();
|
||||||
cluster.waitActive();
|
cluster.waitActive();
|
||||||
|
@ -296,7 +300,8 @@ public class TestOzoneVolumes {
|
||||||
public void testGetVolumesByUser() throws IOException {
|
public void testGetVolumesByUser() throws IOException {
|
||||||
SimpleDateFormat format =
|
SimpleDateFormat format =
|
||||||
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ZZZ", Locale.US);
|
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ZZZ", Locale.US);
|
||||||
|
// We need to create a volume for this test to succeed.
|
||||||
|
testCreateVolumes();
|
||||||
HttpClient client = new DefaultHttpClient();
|
HttpClient client = new DefaultHttpClient();
|
||||||
try {
|
try {
|
||||||
HttpGet httpget =
|
HttpGet httpget =
|
||||||
|
|
|
@ -23,6 +23,7 @@ import static org.apache.hadoop.ozone.web.utils.OzoneUtils.*;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -69,9 +70,8 @@ public class TestOzoneWebAccess {
|
||||||
public static void init() throws IOException {
|
public static void init() throws IOException {
|
||||||
OzoneConfiguration conf = new OzoneConfiguration();
|
OzoneConfiguration conf = new OzoneConfiguration();
|
||||||
|
|
||||||
String path = new Path(
|
URL p = conf.getClass().getResource("");
|
||||||
System.getProperty("test.build.data", "target/test/data"),
|
String path = p.getPath().concat(TestOzoneWebAccess.class.getSimpleName());
|
||||||
TestOzoneWebAccess.class.getSimpleName()).toUri().getPath();
|
|
||||||
conf.set(OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT, path);
|
conf.set(OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT, path);
|
||||||
conf.setBoolean(OzoneConfigKeys.DFS_OBJECTSTORE_ENABLED_KEY, true);
|
conf.setBoolean(OzoneConfigKeys.DFS_OBJECTSTORE_ENABLED_KEY, true);
|
||||||
conf.set(OzoneConfigKeys.DFS_STORAGE_HANDLER_TYPE_KEY, "local");
|
conf.set(OzoneConfigKeys.DFS_STORAGE_HANDLER_TYPE_KEY, "local");
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
* 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.ozone.web.client;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
||||||
|
import org.apache.hadoop.hdfs.server.datanode.DataNode;
|
||||||
|
import org.apache.hadoop.ozone.OzoneConfigKeys;
|
||||||
|
import org.apache.hadoop.ozone.OzoneConfiguration;
|
||||||
|
import org.apache.hadoop.ozone.web.exceptions.OzoneException;
|
||||||
|
import org.apache.hadoop.ozone.web.request.OzoneQuota;
|
||||||
|
import org.apache.hadoop.ozone.web.utils.OzoneConsts;
|
||||||
|
import org.apache.hadoop.ozone.web.utils.OzoneUtils;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class TestVolume {
|
||||||
|
private static MiniDFSCluster cluster = null;
|
||||||
|
private static int port = 0;
|
||||||
|
private static OzoneClient client = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a MiniDFSCluster for testing.
|
||||||
|
* <p>
|
||||||
|
* Ozone is made active by setting DFS_OBJECTSTORE_ENABLED_KEY = true and
|
||||||
|
* DFS_STORAGE_HANDLER_TYPE_KEY = "local" , which uses a local directory to
|
||||||
|
* emulate Ozone backend.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@BeforeClass
|
||||||
|
public static void init() throws IOException, OzoneException,
|
||||||
|
URISyntaxException {
|
||||||
|
OzoneConfiguration conf = new OzoneConfiguration();
|
||||||
|
|
||||||
|
URL p = conf.getClass().getResource("");
|
||||||
|
String path = p.getPath().concat(TestVolume.class.getSimpleName());
|
||||||
|
path += conf.getTrimmed(OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT,
|
||||||
|
OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT_DEFAULT);
|
||||||
|
|
||||||
|
conf.set(OzoneConfigKeys.DFS_STORAGE_LOCAL_ROOT, path);
|
||||||
|
conf.setBoolean(OzoneConfigKeys.DFS_OBJECTSTORE_ENABLED_KEY, true);
|
||||||
|
conf.set(OzoneConfigKeys.DFS_STORAGE_HANDLER_TYPE_KEY, "local");
|
||||||
|
conf.setBoolean(OzoneConfigKeys.DFS_OBJECTSTORE_TRACE_ENABLED_KEY, true);
|
||||||
|
Logger.getLogger("log4j.logger.org.apache.http").setLevel(Level.DEBUG);
|
||||||
|
|
||||||
|
cluster = new MiniDFSCluster.Builder(conf).build();
|
||||||
|
cluster.waitActive();
|
||||||
|
DataNode dataNode = cluster.getDataNodes().get(0);
|
||||||
|
port = dataNode.getInfoPort();
|
||||||
|
|
||||||
|
client = new OzoneClient(String.format("http://localhost:%d", port));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shutdown MiniDFSCluster
|
||||||
|
*/
|
||||||
|
@AfterClass
|
||||||
|
public static void shutdown() {
|
||||||
|
if (cluster != null) {
|
||||||
|
cluster.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateVolume() throws OzoneException {
|
||||||
|
String volumeName = OzoneUtils.getRequestID().toLowerCase();
|
||||||
|
client.setUserAuth(OzoneConsts.OZONE_SIMPLE_HDFS_USER);
|
||||||
|
OzoneVolume vol = client.createVolume(volumeName, "bilbo", "100TB");
|
||||||
|
|
||||||
|
assertEquals(vol.getVolumeName(), volumeName);
|
||||||
|
assertEquals(vol.getCreatedby(), "hdfs");
|
||||||
|
assertEquals(vol.getOwnerName(), "bilbo");
|
||||||
|
assertEquals(vol.getQuota().getUnit(), OzoneQuota.Units.TB);
|
||||||
|
assertEquals(vol.getQuota().getSize(), 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateDuplicateVolume() throws OzoneException {
|
||||||
|
try {
|
||||||
|
client.setUserAuth(OzoneConsts.OZONE_SIMPLE_HDFS_USER);
|
||||||
|
client.createVolume("testvol", "bilbo", "100TB");
|
||||||
|
client.createVolume("testvol", "bilbo", "100TB");
|
||||||
|
assertFalse(true);
|
||||||
|
} catch (OzoneException ex) {
|
||||||
|
// OZone will throw saying volume already exists
|
||||||
|
assertEquals(ex.getShortMessage(),"volumeAlreadyExists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteVolume() throws OzoneException {
|
||||||
|
String volumeName = OzoneUtils.getRequestID().toLowerCase();
|
||||||
|
client.setUserAuth(OzoneConsts.OZONE_SIMPLE_HDFS_USER);
|
||||||
|
OzoneVolume vol = client.createVolume(volumeName, "bilbo", "100TB");
|
||||||
|
client.deleteVolume(vol.getVolumeName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testChangeOwnerOnVolume() throws OzoneException {
|
||||||
|
String volumeName = OzoneUtils.getRequestID().toLowerCase();
|
||||||
|
client.setUserAuth(OzoneConsts.OZONE_SIMPLE_HDFS_USER);
|
||||||
|
OzoneVolume vol = client.createVolume(volumeName, "bilbo", "100TB");
|
||||||
|
client.setVolumeOwner(volumeName, "frodo");
|
||||||
|
OzoneVolume newVol = client.getVolume(volumeName);
|
||||||
|
assertEquals(newVol.getOwnerName(), "frodo");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testChangeQuotaOnVolume() throws OzoneException, IOException {
|
||||||
|
String volumeName = OzoneUtils.getRequestID().toLowerCase();
|
||||||
|
client.setUserAuth(OzoneConsts.OZONE_SIMPLE_HDFS_USER);
|
||||||
|
OzoneVolume vol = client.createVolume(volumeName, "bilbo", "100TB");
|
||||||
|
client.setVolumeQuota(volumeName, "1000MB");
|
||||||
|
OzoneVolume newVol = client.getVolume(volumeName);
|
||||||
|
assertEquals(newVol.getQuota().getSize(), 1000);
|
||||||
|
assertEquals(newVol.getQuota().getUnit(), OzoneQuota.Units.MB);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListVolume() throws OzoneException, IOException {
|
||||||
|
client.setUserAuth(OzoneConsts.OZONE_SIMPLE_HDFS_USER);
|
||||||
|
for (int x = 0; x < 10; x++) {
|
||||||
|
String volumeName = OzoneUtils.getRequestID().toLowerCase();
|
||||||
|
OzoneVolume vol = client.createVolume(volumeName, "frodo", "100TB");
|
||||||
|
assertNotNull(vol);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<OzoneVolume> ovols = client.listVolumes("frodo");
|
||||||
|
assertTrue(ovols.size() >= 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue