/* * Copyright 2015 herd contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.finra.herd.tools.downloader; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; import javax.xml.bind.JAXBException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.finra.herd.model.api.xml.BusinessObjectData; import org.finra.herd.model.api.xml.S3KeyPrefixInformation; import org.finra.herd.model.api.xml.StorageUnitDownloadCredential; import org.finra.herd.model.dto.DataBridgeBaseManifestDto; import org.finra.herd.model.dto.DownloaderInputManifestDto; import org.finra.herd.tools.common.databridge.DataBridgeWebClient; /** * This class encapsulates web client functionality required to communicate with the herd registration service. */ @Component public class DownloaderWebClient extends DataBridgeWebClient { private static final Logger LOGGER = LoggerFactory.getLogger(DownloaderWebClient.class); /** * Retrieves S3 key prefix from the herd registration server. * * @param businessObjectData the business object data * * @return the S3 key prefix * @throws JAXBException if a JAXB error was encountered. * @throws IOException if an I/O error was encountered. * @throws URISyntaxException if a URI syntax error was encountered. */ public S3KeyPrefixInformation getS3KeyPrefix(BusinessObjectData businessObjectData) throws IOException, JAXBException, URISyntaxException { DataBridgeBaseManifestDto dataBridgeBaseManifestDto = new DataBridgeBaseManifestDto(); dataBridgeBaseManifestDto.setNamespace(businessObjectData.getNamespace()); dataBridgeBaseManifestDto.setBusinessObjectDefinitionName(businessObjectData.getBusinessObjectDefinitionName()); dataBridgeBaseManifestDto.setBusinessObjectFormatUsage(businessObjectData.getBusinessObjectFormatUsage()); dataBridgeBaseManifestDto.setBusinessObjectFormatFileType(businessObjectData.getBusinessObjectFormatFileType()); dataBridgeBaseManifestDto.setBusinessObjectFormatVersion(String.valueOf(businessObjectData.getBusinessObjectFormatVersion())); dataBridgeBaseManifestDto.setPartitionKey(businessObjectData.getPartitionKey()); dataBridgeBaseManifestDto.setPartitionValue(businessObjectData.getPartitionValue()); dataBridgeBaseManifestDto.setSubPartitionValues(businessObjectData.getSubPartitionValues()); dataBridgeBaseManifestDto.setStorageName(businessObjectData.getStorageUnits().get(0).getStorage().getName()); return super.getS3KeyPrefix(dataBridgeBaseManifestDto, businessObjectData.getVersion(), Boolean.FALSE); } /** * Retrieves business object data from the herd registration server. * * @param manifest the downloader input manifest file information * * @return the business object data information * @throws JAXBException if a JAXB error was encountered. * @throws IOException if an I/O error was encountered. * @throws URISyntaxException if a URI syntax error was encountered. */ public BusinessObjectData getBusinessObjectData(DownloaderInputManifestDto manifest) throws IOException, JAXBException, URISyntaxException { LOGGER.info("Retrieving business object data information from the registration server..."); StringBuilder uriPathBuilder = new StringBuilder(HERD_APP_REST_URI_PREFIX); uriPathBuilder.append("/businessObjectData"); if (manifest.getNamespace() != null) { uriPathBuilder.append("/namespaces/").append(manifest.getNamespace()); } uriPathBuilder.append("/businessObjectDefinitionNames/").append(manifest.getBusinessObjectDefinitionName()); uriPathBuilder.append("/businessObjectFormatUsages/").append(manifest.getBusinessObjectFormatUsage()); uriPathBuilder.append("/businessObjectFormatFileTypes/").append(manifest.getBusinessObjectFormatFileType()); URIBuilder uriBuilder = new URIBuilder().setScheme(getUriScheme()).setHost(regServerAccessParamsDto.getRegServerHost()).setPort(regServerAccessParamsDto.getRegServerPort()) .setPath(uriPathBuilder.toString()).setParameter("partitionKey", manifest.getPartitionKey()) .setParameter("partitionValue", manifest.getPartitionValue()) .setParameter("businessObjectFormatVersion", manifest.getBusinessObjectFormatVersion()) .setParameter("businessObjectDataVersion", manifest.getBusinessObjectDataVersion()); if (manifest.getSubPartitionValues() != null) { uriBuilder.setParameter("subPartitionValues", herdStringHelper.join(manifest.getSubPartitionValues(), "|", "\\")); } URI uri = uriBuilder.build(); CloseableHttpClient client = httpClientOperations.createHttpClient(); HttpGet request = new HttpGet(uri); request.addHeader("Accepts", "application/xml"); // If SSL is enabled, set the client authentication header. if (regServerAccessParamsDto.getUseSsl()) { request.addHeader(getAuthorizationHeader()); } LOGGER.info(String.format(" HTTP GET URI: %s", request.getURI().toString())); LOGGER.info(String.format(" HTTP GET Headers: %s", Arrays.toString(request.getAllHeaders()))); BusinessObjectData businessObjectData = getBusinessObjectData(httpClientOperations.execute(client, request), "retrieve business object data from the registration server"); LOGGER.info("Successfully retrieved business object data from the registration server."); return businessObjectData; } /** * Gets the storage unit download credentials. * * @param manifest The manifest * @param storageName The storage name * * @return StorageUnitDownloadCredential * @throws URISyntaxException When error occurs while URI creation * @throws IOException When error occurs communicating with server * @throws JAXBException When error occurs parsing XML */ public StorageUnitDownloadCredential getStorageUnitDownloadCredential(DownloaderInputManifestDto manifest, String storageName) throws URISyntaxException, IOException, JAXBException { URIBuilder uriBuilder = new URIBuilder().setScheme(getUriScheme()).setHost(regServerAccessParamsDto.getRegServerHost()).setPort(regServerAccessParamsDto.getRegServerPort()) .setPath(String.join("/", HERD_APP_REST_URI_PREFIX, "storageUnits", "download", "credential", "namespaces", manifest.getNamespace(), "businessObjectDefinitionNames", manifest.getBusinessObjectDefinitionName(), "businessObjectFormatUsages", manifest.getBusinessObjectFormatUsage(), "businessObjectFormatFileTypes", manifest.getBusinessObjectFormatFileType(), "businessObjectFormatVersions", manifest.getBusinessObjectFormatVersion(), "partitionValues", manifest.getPartitionValue(), "businessObjectDataVersions", manifest.getBusinessObjectDataVersion(), "storageNames", storageName)); if (manifest.getSubPartitionValues() != null) { uriBuilder.addParameter("subPartitionValues", herdStringHelper.join(manifest.getSubPartitionValues(), "|", "\\")); } HttpGet httpGet = new HttpGet(uriBuilder.build()); httpGet.addHeader("Accept", DEFAULT_ACCEPT); if (regServerAccessParamsDto.getUseSsl()) { httpGet.addHeader(getAuthorizationHeader()); } try (CloseableHttpClient httpClient = httpClientOperations.createHttpClient()) { LOGGER.info("Retrieving download credentials from registration server..."); return getStorageUnitDownloadCredential(httpClientOperations.execute(httpClient, httpGet)); } } /** * Gets the storage unit download credentials. * * @param response the HTTP response * * @return StorageUnitDownloadCredential */ private StorageUnitDownloadCredential getStorageUnitDownloadCredential(CloseableHttpResponse response) { return (StorageUnitDownloadCredential) processXmlHttpResponse(response, "get storage unit download credential", StorageUnitDownloadCredential.class); } }