| /* |
| * 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 com.google.common.annotations.VisibleForTesting; |
| import com.google.common.base.Strings; |
| |
| import org.apache.commons.codec.digest.DigestUtils; |
| import org.apache.commons.lang.StringUtils; |
| import org.apache.hadoop.hdds.scm.client.HddsClientUtils; |
| import org.apache.hadoop.io.IOUtils; |
| import org.apache.hadoop.ozone.client.rest.OzoneException; |
| import org.apache.hadoop.ozone.client.rest.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 static org.apache.hadoop.hdds.server.ServerUtils.releaseConnection; |
| 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.entity.ContentType; |
| import org.apache.http.entity.FileEntity; |
| import org.apache.http.impl.client.CloseableHttpClient; |
| import org.apache.http.util.EntityUtils; |
| |
| import javax.ws.rs.core.HttpHeaders; |
| import java.io.Closeable; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.nio.file.Path; |
| 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 OzoneRestClient implements Closeable { |
| private URI endPointURI; |
| private String userAuth; |
| |
| /** |
| * Constructor for OzoneRestClient. |
| */ |
| public OzoneRestClient() { |
| } |
| |
| /** |
| * Constructor for OzoneRestClient. |
| */ |
| public OzoneRestClient(String ozoneURI) |
| throws OzoneException, URISyntaxException { |
| setEndPoint(ozoneURI); |
| } |
| |
| /** |
| * Constructor for OzoneRestClient. |
| */ |
| public OzoneRestClient(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 OzoneRestClientException("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 OzoneRestClientException |
| */ |
| public OzoneVolume createVolume(String volumeName, String onBehalfOf, |
| String quota) throws OzoneException { |
| HttpPost httpPost = null; |
| try (CloseableHttpClient httpClient = newHttpClient()) { |
| OzoneUtils.verifyResourceName(volumeName); |
| |
| URIBuilder builder = new URIBuilder(endPointURI); |
| builder.setPath("/" + volumeName); |
| if (quota != null) { |
| builder.setParameter(Header.OZONE_QUOTA_QUERY_TAG, quota); |
| } |
| |
| httpPost = getHttpPost(onBehalfOf, builder.build().toString()); |
| executeCreateVolume(httpPost, httpClient); |
| return getVolume(volumeName); |
| } catch (IOException | URISyntaxException | IllegalArgumentException ex) { |
| throw new OzoneRestClientException(ex.getMessage(), ex); |
| } finally { |
| releaseConnection(httpPost); |
| } |
| } |
| |
| /** |
| * 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 { |
| HttpGet httpGet = null; |
| try (CloseableHttpClient httpClient = newHttpClient()) { |
| OzoneUtils.verifyResourceName(volumeName); |
| URIBuilder builder = new URIBuilder(endPointURI); |
| builder.setPath("/" + volumeName) |
| .setParameter(Header.OZONE_INFO_QUERY_TAG, |
| Header.OZONE_INFO_QUERY_VOLUME) |
| .build(); |
| |
| httpGet = getHttpGet(builder.toString()); |
| return executeInfoVolume(httpGet, httpClient); |
| } catch (IOException | URISyntaxException | IllegalArgumentException ex) { |
| throw new OzoneRestClientException(ex.getMessage(), ex); |
| } finally { |
| releaseConnection(httpGet); |
| } |
| } |
| |
| /** |
| * 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. |
| * @param prefix |
| * Return only volumes that match this prefix. |
| * @param maxKeys |
| * Maximum number of results to return, if the result set |
| * is smaller than requested size, it means that list is |
| * complete. |
| * @param previousVolume |
| * The previous volume name. |
| * @return List of Volumes |
| * @throws OzoneException |
| */ |
| public List<OzoneVolume> listVolumes(String onBehalfOf, String prefix, |
| int maxKeys, String previousVolume) throws OzoneException { |
| HttpGet httpGet = null; |
| try (CloseableHttpClient httpClient = newHttpClient()) { |
| URIBuilder builder = new URIBuilder(endPointURI); |
| if (!Strings.isNullOrEmpty(prefix)) { |
| builder.addParameter(Header.OZONE_LIST_QUERY_PREFIX, prefix); |
| } |
| |
| if (maxKeys > 0) { |
| builder.addParameter(Header.OZONE_LIST_QUERY_MAXKEYS, Integer |
| .toString(maxKeys)); |
| } |
| |
| if (!Strings.isNullOrEmpty(previousVolume)) { |
| builder.addParameter(Header.OZONE_LIST_QUERY_PREVKEY, |
| previousVolume); |
| } |
| |
| builder.setPath("/").build(); |
| |
| httpGet = getHttpGet(builder.toString()); |
| if (onBehalfOf != null) { |
| httpGet.addHeader(Header.OZONE_USER, onBehalfOf); |
| } |
| return executeListVolume(httpGet, httpClient); |
| } catch (IOException | URISyntaxException ex) { |
| throw new OzoneRestClientException(ex.getMessage(), ex); |
| } finally { |
| releaseConnection(httpGet); |
| } |
| } |
| |
| /** |
| * 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. |
| * @param prefix - Return only volumes that match this prefix. |
| * @param maxKeys - Maximum number of results to return, if the result set |
| * is smaller than requested size, it means that list is |
| * complete. |
| * @param prevKey - The last key that client got, server will continue |
| * returning results from that point. |
| * @return List of Volumes |
| * @throws OzoneException |
| */ |
| public List<OzoneVolume> listVolumes(String onBehalfOf, String prefix, |
| int maxKeys, OzoneVolume prevKey) throws OzoneException { |
| String volumeName = null; |
| |
| if (prevKey != null) { |
| volumeName = prevKey.getVolumeName(); |
| } |
| |
| return listVolumes(onBehalfOf, prefix, maxKeys, volumeName); |
| } |
| |
| /** |
| * List volumes of the current user or if onBehalfof is not null lists volume |
| * owned by that user. You need admin privilege to read other users volume |
| * lists. |
| * |
| * @param onBehalfOf - Name of the user you want to get volume list |
| * @return - Volume list. |
| * @throws OzoneException |
| */ |
| public List<OzoneVolume> listVolumes(String onBehalfOf) |
| throws OzoneException { |
| return listVolumes(onBehalfOf, null, |
| Integer.parseInt(Header.OZONE_DEFAULT_LIST_SIZE), StringUtils.EMPTY); |
| } |
| |
| /** |
| * List all volumes in a cluster. This can be invoked only by an Admin. |
| * |
| * @param prefix - Returns only volumes that match this prefix. |
| * @param maxKeys - Maximum niumber of keys to return |
| * @param prevKey - Last Ozone Volume from the last Iteration. |
| * @return List of Volumes |
| * @throws OzoneException |
| */ |
| public List<OzoneVolume> listAllVolumes(String prefix, int maxKeys, |
| OzoneVolume prevKey) throws OzoneException { |
| HttpGet httpGet = null; |
| try (CloseableHttpClient httpClient = newHttpClient()) { |
| URIBuilder builder = new URIBuilder(endPointURI); |
| if (prefix != null) { |
| builder.addParameter(Header.OZONE_LIST_QUERY_PREFIX, prefix); |
| } |
| |
| if (maxKeys > 0) { |
| builder.addParameter(Header.OZONE_LIST_QUERY_MAXKEYS, Integer |
| .toString(maxKeys)); |
| } |
| |
| if (prevKey != null) { |
| builder.addParameter(Header.OZONE_LIST_QUERY_PREVKEY, |
| prevKey.getOwnerName()+ "/" + prevKey.getVolumeName()); |
| } |
| |
| builder.addParameter(Header.OZONE_LIST_QUERY_ROOTSCAN, "true"); |
| builder.setPath("/").build(); |
| httpGet = getHttpGet(builder.toString()); |
| return executeListVolume(httpGet, httpClient); |
| |
| } catch (IOException | URISyntaxException ex) { |
| throw new OzoneRestClientException(ex.getMessage(), ex); |
| } finally { |
| releaseConnection(httpGet); |
| } |
| } |
| |
| /** |
| * delete a given volume. |
| * |
| * @param volumeName - volume to be deleted. |
| * @throws OzoneException - Ozone Exception |
| */ |
| public void deleteVolume(String volumeName) throws OzoneException { |
| HttpDelete httpDelete = null; |
| try (CloseableHttpClient httpClient = newHttpClient()) { |
| OzoneUtils.verifyResourceName(volumeName); |
| URIBuilder builder = new URIBuilder(endPointURI); |
| builder.setPath("/" + volumeName).build(); |
| |
| httpDelete = getHttpDelete(builder.toString()); |
| executeDeleteVolume(httpDelete, httpClient); |
| } catch (IOException | URISyntaxException | IllegalArgumentException ex) { |
| throw new OzoneRestClientException(ex.getMessage(), ex); |
| } finally { |
| releaseConnection(httpDelete); |
| } |
| } |
| |
| /** |
| * Sets the Volume Owner. |
| * |
| * @param volumeName - Volume Name |
| * @param newOwner - New Owner Name |
| * @throws OzoneException |
| */ |
| public void setVolumeOwner(String volumeName, String newOwner) |
| throws OzoneException { |
| HttpPut putRequest = null; |
| if (newOwner == null || newOwner.isEmpty()) { |
| throw new OzoneRestClientException("Invalid new owner name"); |
| } |
| try (CloseableHttpClient httpClient = newHttpClient()) { |
| OzoneUtils.verifyResourceName(volumeName); |
| URIBuilder builder = new URIBuilder(endPointURI); |
| builder.setPath("/" + volumeName).build(); |
| |
| putRequest = getHttpPut(builder.toString()); |
| putRequest.addHeader(Header.OZONE_USER, newOwner); |
| executePutVolume(putRequest, httpClient); |
| |
| } catch (URISyntaxException | IllegalArgumentException | IOException ex) { |
| throw new OzoneRestClientException(ex.getMessage(), ex); |
| } finally { |
| releaseConnection(putRequest); |
| } |
| } |
| |
| /** |
| * 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 OzoneRestClientException("Invalid quota"); |
| } |
| HttpPut putRequest = null; |
| try (CloseableHttpClient httpClient = newHttpClient()) { |
| OzoneUtils.verifyResourceName(volumeName); |
| URIBuilder builder = new URIBuilder(endPointURI); |
| builder.setPath("/" + volumeName) |
| .setParameter(Header.OZONE_QUOTA_QUERY_TAG, quota) |
| .build(); |
| |
| putRequest = getHttpPut(builder.toString()); |
| executePutVolume(putRequest, httpClient); |
| |
| } catch (URISyntaxException | IllegalArgumentException | IOException ex) { |
| throw new OzoneRestClientException(ex.getMessage(), ex); |
| } finally { |
| releaseConnection(putRequest); |
| } |
| } |
| |
| /** |
| * 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, |
| final CloseableHttpClient 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 OzoneRestClientException("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, |
| final CloseableHttpClient 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 OzoneRestClientException("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, |
| final CloseableHttpClient 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, |
| final CloseableHttpClient 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 OzoneRestClientException("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, |
| final CloseableHttpClient 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); |
| } |
| } |
| } |
| |
| /** |
| * Puts a Key in Ozone Bucket. |
| * |
| * @param volumeName - Name of the Volume |
| * @param bucketName - Name of the Bucket |
| * @param keyName - Name of the Key |
| * @param file - Stream that gets read to be put into Ozone. |
| * @throws OzoneException |
| */ |
| public void putKey(String volumeName, String bucketName, String keyName, |
| File file) throws OzoneException { |
| OzoneUtils.verifyResourceName(volumeName); |
| OzoneUtils.verifyResourceName(bucketName); |
| |
| if (StringUtils.isEmpty(keyName)) { |
| throw new OzoneRestClientException("Invalid key Name"); |
| } |
| |
| if (file == null) { |
| throw new OzoneRestClientException("Invalid data stream"); |
| } |
| |
| HttpPut putRequest = null; |
| FileInputStream fis = null; |
| try (CloseableHttpClient httpClient = HddsClientUtils.newHttpClient()) { |
| URIBuilder builder = new URIBuilder(getEndPointURI()); |
| builder.setPath("/" + volumeName + "/" + bucketName + "/" + keyName) |
| .build(); |
| |
| putRequest = getHttpPut(builder.toString()); |
| |
| FileEntity fileEntity = new FileEntity(file, ContentType |
| .APPLICATION_OCTET_STREAM); |
| putRequest.setEntity(fileEntity); |
| |
| fis = new FileInputStream(file); |
| putRequest.setHeader(Header.CONTENT_MD5, DigestUtils.md5Hex(fis)); |
| OzoneBucket.executePutKey(putRequest, httpClient); |
| } catch (IOException | URISyntaxException ex) { |
| throw new OzoneRestClientException(ex.getMessage(), ex); |
| } finally { |
| IOUtils.closeStream(fis); |
| releaseConnection(putRequest); |
| } |
| } |
| |
| /** |
| * Gets a key from the Ozone server and writes to the file pointed by the |
| * downloadTo Path. |
| * |
| * @param volumeName - Volume Name in Ozone. |
| * @param bucketName - Bucket Name in Ozone. |
| * @param keyName - Key Name in Ozone. |
| * @param downloadTo File Name to download the Key's Data to |
| */ |
| public void getKey(String volumeName, String bucketName, String keyName, |
| Path downloadTo) throws OzoneException { |
| OzoneUtils.verifyResourceName(volumeName); |
| OzoneUtils.verifyResourceName(bucketName); |
| |
| if (StringUtils.isEmpty(keyName)) { |
| throw new OzoneRestClientException("Invalid key Name"); |
| } |
| |
| if (downloadTo == null) { |
| throw new OzoneRestClientException("Invalid download path"); |
| } |
| |
| FileOutputStream outPutFile = null; |
| HttpGet getRequest = null; |
| try (CloseableHttpClient httpClient = HddsClientUtils.newHttpClient()) { |
| outPutFile = new FileOutputStream(downloadTo.toFile()); |
| |
| URIBuilder builder = new URIBuilder(getEndPointURI()); |
| builder.setPath("/" + volumeName + "/" + bucketName + "/" + keyName) |
| .build(); |
| |
| getRequest = getHttpGet(builder.toString()); |
| OzoneBucket.executeGetKey(getRequest, httpClient, outPutFile); |
| outPutFile.flush(); |
| } catch (IOException | URISyntaxException ex) { |
| throw new OzoneRestClientException(ex.getMessage(), ex); |
| } finally { |
| IOUtils.closeStream(outPutFile); |
| releaseConnection(getRequest); |
| } |
| } |
| |
| /** |
| * List all keys in the given bucket. |
| * |
| * @param volumeName - Volume name |
| * @param bucketName - Bucket name |
| * @param resultLength The max length of listing result. |
| * @param previousKey The key from where listing should start, |
| * this key is excluded in the result. |
| * @param prefix The prefix that return list keys start with. |
| * |
| * @return List of OzoneKeys |
| */ |
| public List<OzoneKey> listKeys(String volumeName, String bucketName, |
| String resultLength, String previousKey, String prefix) |
| throws OzoneException { |
| OzoneUtils.verifyResourceName(volumeName); |
| OzoneUtils.verifyResourceName(bucketName); |
| |
| HttpGet getRequest = null; |
| try (CloseableHttpClient httpClient = HddsClientUtils.newHttpClient()) { |
| URIBuilder builder = new URIBuilder(getEndPointURI()); |
| builder.setPath("/" + volumeName + "/" + bucketName).build(); |
| |
| if (!Strings.isNullOrEmpty(resultLength)) { |
| builder.addParameter(Header.OZONE_LIST_QUERY_MAXKEYS, resultLength); |
| } |
| |
| if (!Strings.isNullOrEmpty(previousKey)) { |
| builder.addParameter(Header.OZONE_LIST_QUERY_PREVKEY, previousKey); |
| } |
| |
| if (!Strings.isNullOrEmpty(prefix)) { |
| builder.addParameter(Header.OZONE_LIST_QUERY_PREFIX, prefix); |
| } |
| |
| getRequest = getHttpGet(builder.toString()); |
| return OzoneBucket.executeListKeys(getRequest, httpClient); |
| } catch (IOException | URISyntaxException e) { |
| throw new OzoneRestClientException(e.getMessage(), e); |
| } finally { |
| releaseConnection(getRequest); |
| } |
| } |
| |
| /** |
| * 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. |
| } |
| |
| @VisibleForTesting |
| public CloseableHttpClient newHttpClient() { |
| return HddsClientUtils.newHttpClient(); |
| } |
| } |