HDFS-9845. OzoneHandler : Support List and Info Volumes. Contributed by Anu Engineer.
This commit is contained in:
parent
ed258dc633
commit
40211dd4fe
|
@ -33,3 +33,6 @@
|
||||||
|
|
||||||
HDFS-9834. OzoneHandler : Enable MiniDFSCluster based testing for Ozone.
|
HDFS-9834. OzoneHandler : Enable MiniDFSCluster based testing for Ozone.
|
||||||
(Anu Engineer via cnauroth)
|
(Anu Engineer via cnauroth)
|
||||||
|
|
||||||
|
HDFS-9845. OzoneHandler : Support List and Info Volumes.
|
||||||
|
(Anu Engineer via cnauroth)
|
||||||
|
|
|
@ -17,15 +17,18 @@
|
||||||
*/
|
*/
|
||||||
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 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 java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.ozone.web.handlers.ServiceFilter;
|
||||||
import org.apache.hadoop.ozone.web.interfaces.StorageHandler;
|
import org.apache.hadoop.ozone.web.interfaces.StorageHandler;
|
||||||
import org.apache.hadoop.ozone.web.ObjectStoreApplication;
|
import org.apache.hadoop.ozone.web.ObjectStoreApplication;
|
||||||
import org.apache.hadoop.ozone.web.netty.ObjectStoreJerseyContainer;
|
import org.apache.hadoop.ozone.web.netty.ObjectStoreJerseyContainer;
|
||||||
|
@ -62,9 +65,13 @@ public final class ObjectStoreHandler {
|
||||||
DFS_STORAGE_HANDLER_TYPE_KEY, shType));
|
DFS_STORAGE_HANDLER_TYPE_KEY, shType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ApplicationAdapter aa =
|
||||||
|
new ApplicationAdapter(new ObjectStoreApplication());
|
||||||
|
aa.setPropertiesAndFeatures(Collections.<String, Object>singletonMap(
|
||||||
|
PROPERTY_CONTAINER_REQUEST_FILTERS,
|
||||||
|
ServiceFilter.class.getCanonicalName()));
|
||||||
this.objectStoreJerseyContainer = ContainerFactory.createContainer(
|
this.objectStoreJerseyContainer = ContainerFactory.createContainer(
|
||||||
ObjectStoreJerseyContainer.class, new ApplicationAdapter(
|
ObjectStoreJerseyContainer.class, aa);
|
||||||
new ObjectStoreApplication()));
|
|
||||||
this.objectStoreJerseyContainer.setStorageHandler(storageHandler);
|
this.objectStoreJerseyContainer.setStorageHandler(storageHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.hadoop.ozone.web;
|
||||||
|
|
||||||
import org.apache.hadoop.ozone.web.exceptions.OzoneExceptionMapper;
|
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.VolumeHandler;
|
import org.apache.hadoop.ozone.web.handlers.VolumeHandler;
|
||||||
|
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
||||||
|
@ -46,6 +47,7 @@ public class ObjectStoreApplication extends Application {
|
||||||
@Override
|
@Override
|
||||||
public Set<Object> getSingletons() {
|
public Set<Object> getSingletons() {
|
||||||
HashSet<Object> set = new HashSet<>();
|
HashSet<Object> set = new HashSet<>();
|
||||||
|
set.add(ServiceFilter.class);
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* 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.handlers;
|
||||||
|
|
||||||
|
import com.sun.jersey.spi.container.ContainerRequest;
|
||||||
|
import com.sun.jersey.spi.container.ContainerRequestFilter;
|
||||||
|
import org.apache.hadoop.ozone.web.headers.Header;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
import javax.ws.rs.ext.Provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to intercept root URL requests and route it to
|
||||||
|
* Volume List functionality.
|
||||||
|
*/
|
||||||
|
@Provider
|
||||||
|
public class ServiceFilter implements ContainerRequestFilter {
|
||||||
|
/**
|
||||||
|
* Filter the request.
|
||||||
|
* <p>
|
||||||
|
* An implementation may modify the state of the request or
|
||||||
|
* create a new instance.
|
||||||
|
*
|
||||||
|
* @param request the request.
|
||||||
|
*
|
||||||
|
* @return the request.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ContainerRequest filter(ContainerRequest request) {
|
||||||
|
if (request.getRequestUri().getPath().length() > 1) {
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just re-route it to volume handler with some hypothetical volume name.
|
||||||
|
// volume name is ignored.
|
||||||
|
|
||||||
|
request.setUris(request.getBaseUri(),
|
||||||
|
UriBuilder.fromUri(request.getRequestUri())
|
||||||
|
.path("/service")
|
||||||
|
.queryParam("info", Header.OZONE_LIST_QUERY_SERVICE)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ import org.apache.hadoop.ozone.web.utils.OzoneUtils;
|
||||||
import org.apache.hadoop.util.Time;
|
import org.apache.hadoop.util.Time;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
|
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.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -42,6 +43,7 @@ import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static java.net.HttpURLConnection.HTTP_CREATED;
|
import static java.net.HttpURLConnection.HTTP_CREATED;
|
||||||
|
import static java.net.HttpURLConnection.HTTP_OK;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class TestOzoneVolumes {
|
public class TestOzoneVolumes {
|
||||||
|
@ -241,7 +243,7 @@ public class TestOzoneVolumes {
|
||||||
format.format(new Date(Time.monotonicNow())));
|
format.format(new Date(Time.monotonicNow())));
|
||||||
httppost.addHeader(HttpHeaders.AUTHORIZATION,
|
httppost.addHeader(HttpHeaders.AUTHORIZATION,
|
||||||
Header.OZONE_SIMPLE_AUTHENTICATION_SCHEME + " " +
|
Header.OZONE_SIMPLE_AUTHENTICATION_SCHEME + " " +
|
||||||
"bilbo"); // This is not a root user in Simple
|
"bilbo"); // This is not a root user in Simple Auth
|
||||||
httppost.addHeader(Header.OZONE_USER, OzoneConsts.OZONE_SIMPLE_HDFS_USER);
|
httppost.addHeader(Header.OZONE_USER, OzoneConsts.OZONE_SIMPLE_HDFS_USER);
|
||||||
|
|
||||||
HttpResponse response = client.execute(httppost);
|
HttpResponse response = client.execute(httppost);
|
||||||
|
@ -253,7 +255,7 @@ public class TestOzoneVolumes {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a bunch of volumes in a loop
|
* Create a bunch of volumes in a loop.
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
|
@ -285,4 +287,117 @@ public class TestOzoneVolumes {
|
||||||
client.getConnectionManager().shutdown();
|
client.getConnectionManager().shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Get volumes owned by the user.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetVolumesByUser() throws IOException {
|
||||||
|
SimpleDateFormat format =
|
||||||
|
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ZZZ", Locale.US);
|
||||||
|
|
||||||
|
HttpClient client = new DefaultHttpClient();
|
||||||
|
try {
|
||||||
|
HttpGet httpget =
|
||||||
|
new HttpGet(String.format("http://localhost:%d/", port));
|
||||||
|
|
||||||
|
httpget.addHeader(Header.OZONE_VERSION_HEADER,
|
||||||
|
Header.OZONE_V1_VERSION_HEADER);
|
||||||
|
|
||||||
|
httpget.addHeader(HttpHeaders.DATE,
|
||||||
|
format.format(new Date(Time.monotonicNow())));
|
||||||
|
|
||||||
|
httpget.addHeader(HttpHeaders.AUTHORIZATION,
|
||||||
|
Header.OZONE_SIMPLE_AUTHENTICATION_SCHEME + " " +
|
||||||
|
OzoneConsts.OZONE_SIMPLE_HDFS_USER);
|
||||||
|
|
||||||
|
httpget.addHeader(Header.OZONE_USER,
|
||||||
|
OzoneConsts.OZONE_SIMPLE_HDFS_USER );
|
||||||
|
|
||||||
|
HttpResponse response = client.execute(httpget);
|
||||||
|
assertEquals(response.toString(), HTTP_OK,
|
||||||
|
response.getStatusLine().getStatusCode());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
client.getConnectionManager().shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admins can read volumes belonging to other users.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetVolumesOfAnotherUser() throws IOException {
|
||||||
|
SimpleDateFormat format =
|
||||||
|
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ZZZ", Locale.US);
|
||||||
|
|
||||||
|
HttpClient client = new DefaultHttpClient();
|
||||||
|
try {
|
||||||
|
HttpGet httpget =
|
||||||
|
new HttpGet(String.format("http://localhost:%d/", port));
|
||||||
|
|
||||||
|
httpget.addHeader(Header.OZONE_VERSION_HEADER,
|
||||||
|
Header.OZONE_V1_VERSION_HEADER);
|
||||||
|
httpget.addHeader(HttpHeaders.DATE,
|
||||||
|
format.format(new Date(Time.monotonicNow())));
|
||||||
|
|
||||||
|
httpget.addHeader(HttpHeaders.AUTHORIZATION,
|
||||||
|
Header.OZONE_SIMPLE_AUTHENTICATION_SCHEME + " " +
|
||||||
|
OzoneConsts.OZONE_SIMPLE_ROOT_USER);
|
||||||
|
|
||||||
|
// User Root is getting volumes belonging to user HDFS
|
||||||
|
httpget.addHeader(Header.OZONE_USER, OzoneConsts.OZONE_SIMPLE_HDFS_USER);
|
||||||
|
|
||||||
|
HttpResponse response = client.execute(httpget);
|
||||||
|
assertEquals(response.toString(), HTTP_OK,
|
||||||
|
response.getStatusLine().getStatusCode());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
client.getConnectionManager().shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if you try to read volumes belonging to another user,
|
||||||
|
* then server always ignores it.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetVolumesOfAnotherUserShouldFail() throws IOException {
|
||||||
|
SimpleDateFormat format =
|
||||||
|
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ZZZ", Locale.US);
|
||||||
|
|
||||||
|
HttpClient client = new DefaultHttpClient();
|
||||||
|
String userName = OzoneUtils.getRequestID().toLowerCase();
|
||||||
|
try {
|
||||||
|
HttpGet httpget =
|
||||||
|
new HttpGet(String.format("http://localhost:%d/", port));
|
||||||
|
|
||||||
|
httpget.addHeader(Header.OZONE_VERSION_HEADER,
|
||||||
|
Header.OZONE_V1_VERSION_HEADER);
|
||||||
|
httpget.addHeader(HttpHeaders.DATE,
|
||||||
|
format.format(new Date(Time.monotonicNow())));
|
||||||
|
|
||||||
|
httpget.addHeader(HttpHeaders.AUTHORIZATION,
|
||||||
|
Header.OZONE_SIMPLE_AUTHENTICATION_SCHEME + " " +
|
||||||
|
userName);
|
||||||
|
|
||||||
|
// userName is NOT a root user, hence he should NOT be able to read the
|
||||||
|
// volumes of user HDFS
|
||||||
|
httpget.addHeader(Header.OZONE_USER, OzoneConsts.OZONE_SIMPLE_HDFS_USER);
|
||||||
|
|
||||||
|
HttpResponse response = client.execute(httpget);
|
||||||
|
// We will get an Error called userNotFound when using Simple Auth Scheme
|
||||||
|
assertEquals(response.toString(), ErrorTable.USER_NOT_FOUND.getHttpCode(),
|
||||||
|
response.getStatusLine().getStatusCode());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
client.getConnectionManager().shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue