Search in sources :

Example 41 with Pair

use of com.github.ambry.utils.Pair in project ambry by linkedin.

the class AmbrySecurityServiceTest method testGetSubResource.

/**
 * Tests GET of sub-resources.
 * @param subResource the {@link RestUtils.SubResource}  to test.
 * @throws Exception
 */
private void testGetSubResource(BlobInfo blobInfo, RestUtils.SubResource subResource) throws Exception {
    MockRestResponseChannel restResponseChannel = new MockRestResponseChannel();
    RestRequest restRequest = createRestRequest(RestMethod.GET, "/sampleId/" + subResource, null);
    Pair<Account, Container> accountAndContainer = getAccountAndContainer(blobInfo.getBlobProperties());
    insertAccountAndContainer(restRequest, accountAndContainer.getFirst(), accountAndContainer.getSecond());
    securityService.processResponse(restRequest, restResponseChannel, blobInfo).get();
    Assert.assertEquals("ProcessResponse status should have been set ", ResponseStatus.Ok, restResponseChannel.getStatus());
    Assert.assertNotNull("Date has not been set", restResponseChannel.getHeader(RestUtils.Headers.DATE));
    Assert.assertEquals("Last Modified does not match creation time", RestUtils.toSecondsPrecisionInMs(blobInfo.getBlobProperties().getCreationTimeInMs()), RestUtils.getTimeFromDateString(restResponseChannel.getHeader(RestUtils.Headers.LAST_MODIFIED)).longValue());
    if (subResource.equals(RestUtils.SubResource.BlobInfo)) {
        verifyBlobPropertiesHeaders(blobInfo.getBlobProperties(), restResponseChannel);
        verifyAccountAndContainerHeaders(restResponseChannel, accountAndContainer.getFirst(), accountAndContainer.getSecond());
        Assert.assertEquals("LifeVersion mismatch", Short.toString(blobInfo.getLifeVersion()), restResponseChannel.getHeader(RestUtils.Headers.LIFE_VERSION));
    } else {
        verifyAbsenceOfHeaders(restResponseChannel, RestUtils.Headers.PRIVATE, RestUtils.Headers.TTL, RestUtils.Headers.SERVICE_ID, RestUtils.Headers.OWNER_ID, RestUtils.Headers.AMBRY_CONTENT_TYPE, RestUtils.Headers.CREATION_TIME, RestUtils.Headers.BLOB_SIZE, RestUtils.Headers.ACCEPT_RANGES, RestUtils.Headers.CONTENT_RANGE, RestUtils.Headers.LIFE_VERSION);
    }
    Map<String, String> userMetadata = blobInfo.getUserMetadata() != null ? RestUtils.buildUserMetadata(blobInfo.getUserMetadata()) : null;
    if (userMetadata == null && !(blobInfo.getUserMetadata().length == 0)) {
        Assert.assertTrue("Internal key " + RestUtils.InternalKeys.SEND_USER_METADATA_AS_RESPONSE_BODY + " should be set", (Boolean) restRequest.getArgs().get(RestUtils.InternalKeys.SEND_USER_METADATA_AS_RESPONSE_BODY));
    } else if (!(blobInfo.getUserMetadata().length == 0)) {
        USER_METADATA.forEach((key, value) -> Assert.assertEquals("Value of " + key + " not as expected", value, restResponseChannel.getHeader(key)));
    }
}
Also used : MockRestRequest(com.github.ambry.rest.MockRestRequest) FrontendConfig(com.github.ambry.config.FrontendConfig) BlobProperties(com.github.ambry.messageformat.BlobProperties) Date(java.util.Date) URISyntaxException(java.net.URISyntaxException) ResponseStatus(com.github.ambry.rest.ResponseStatus) ByteBuffer(java.nio.ByteBuffer) ThrowingConsumer(com.github.ambry.utils.ThrowingConsumer) Future(java.util.concurrent.Future) JSONException(org.json.JSONException) JSONObject(org.json.JSONObject) HostThrottleConfig(com.github.ambry.config.HostThrottleConfig) TestUtils(com.github.ambry.utils.TestUtils) Locale(java.util.Locale) Map(java.util.Map) Container(com.github.ambry.account.Container) TimeZone(java.util.TimeZone) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) RestServiceErrorCode(com.github.ambry.rest.RestServiceErrorCode) Utils(com.github.ambry.utils.Utils) BlobInfo(com.github.ambry.messageformat.BlobInfo) RestServiceException(com.github.ambry.rest.RestServiceException) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) QuotaTestUtils(com.github.ambry.quota.QuotaTestUtils) Account(com.github.ambry.account.Account) Callback(com.github.ambry.commons.Callback) RestUtils(com.github.ambry.rest.RestUtils) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InMemAccountService(com.github.ambry.account.InMemAccountService) ByteRanges(com.github.ambry.router.ByteRanges) SimpleDateFormat(java.text.SimpleDateFormat) AccountService(com.github.ambry.account.AccountService) HashMap(java.util.HashMap) RestTestUtils(com.github.ambry.rest.RestTestUtils) QuotaManager(com.github.ambry.quota.QuotaManager) QuotaConfig(com.github.ambry.config.QuotaConfig) RequestPath(com.github.ambry.rest.RequestPath) QuotaMode(com.github.ambry.quota.QuotaMode) HostLevelThrottler(com.github.ambry.commons.HostLevelThrottler) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) Pair(com.github.ambry.utils.Pair) RestMethod(com.github.ambry.rest.RestMethod) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ByteRange(com.github.ambry.router.ByteRange) IOException(java.io.IOException) Test(org.junit.Test) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) InMemAccountServiceFactory(com.github.ambry.account.InMemAccountServiceFactory) AmbryQuotaManager(com.github.ambry.quota.AmbryQuotaManager) Mockito(org.mockito.Mockito) QuotaMetrics(com.github.ambry.quota.QuotaMetrics) SimpleQuotaRecommendationMergePolicy(com.github.ambry.quota.SimpleQuotaRecommendationMergePolicy) Assert(org.junit.Assert) RestRequest(com.github.ambry.rest.RestRequest) Collections(java.util.Collections) Account(com.github.ambry.account.Account) Container(com.github.ambry.account.Container) MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel)

Example 42 with Pair

use of com.github.ambry.utils.Pair in project ambry by linkedin.

the class AmbrySecurityServiceTest method getAccountAndContainer.

/**
 * @param blobProperties the {@link BlobProperties} to read.
 * @return the {@link Account} and {@link Container} objects corresponding to the IDs in the {@link BlobProperties}.
 */
private Pair<Account, Container> getAccountAndContainer(BlobProperties blobProperties) {
    Account account = ACCOUNT_SERVICE.getAccountById(blobProperties.getAccountId());
    Container container = account.getContainerById(blobProperties.getContainerId());
    return new Pair<>(account, container);
}
Also used : Account(com.github.ambry.account.Account) Container(com.github.ambry.account.Container) Pair(com.github.ambry.utils.Pair)

Example 43 with Pair

use of com.github.ambry.utils.Pair in project ambry by linkedin.

the class FrontendIntegrationTest method uploadDataChunksAndVerify.

/**
 * Upload data chunks using chunk upload signed URL.
 * @param account the {@link Account} to upload into.
 * @param container the {@link Container} to upload into.
 * @param chunkSizes The sizes for each data chunk to upload.
 * @return the list of signed chunk IDs for the uploaded chunks and an array containing the concatenated content of
 *         the data chunks.
 * @throws Exception
 */
private Pair<List<String>, byte[]> uploadDataChunksAndVerify(Account account, Container container, int... chunkSizes) throws Exception {
    IdSigningService idSigningService = new AmbryIdSigningService();
    HttpHeaders chunkUploadHeaders = new DefaultHttpHeaders();
    chunkUploadHeaders.add(RestUtils.Headers.URL_TYPE, RestMethod.POST.name());
    chunkUploadHeaders.add(RestUtils.Headers.CHUNK_UPLOAD, "true");
    setAmbryHeadersForPut(chunkUploadHeaders, TTL_SECS, !container.isCacheable(), "chunkUploader", "application/octet-stream", "stitchedUploadTest", account.getName(), container.getName());
    // POST
    // Get signed URL
    FullHttpRequest httpRequest = buildRequest(HttpMethod.GET, Operations.GET_SIGNED_URL, chunkUploadHeaders, null);
    ResponseParts responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    HttpResponse response = getHttpResponse(responseParts);
    assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
    verifyTrackingHeaders(response);
    String signedPostUrl = response.headers().get(RestUtils.Headers.SIGNED_URL);
    assertNotNull("Did not get a signed POST URL", signedPostUrl);
    assertNoContent(responseParts.queue, 1);
    List<String> signedChunkIds = new ArrayList<>();
    ByteArrayOutputStream fullContentStream = new ByteArrayOutputStream();
    URI uri = new URI(signedPostUrl);
    for (int chunkSize : chunkSizes) {
        byte[] contentArray = TestUtils.getRandomBytes(chunkSize);
        ByteBuffer content = ByteBuffer.wrap(contentArray);
        // Use signed URL to POST
        httpRequest = buildRequest(HttpMethod.POST, uri.getPath() + "?" + uri.getQuery(), null, content);
        responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
        String signedId = verifyPostAndReturnBlobId(responseParts, chunkSize, false);
        assertTrue("Blob ID for chunk upload must be signed", idSigningService.isIdSigned(signedId.substring(1)));
        Pair<String, Map<String, String>> idAndMetadata = idSigningService.parseSignedId(signedId.substring(1));
        // Inspect metadata fields
        String chunkUploadSession = idAndMetadata.getSecond().get(RestUtils.Headers.SESSION);
        assertNotNull("x-ambry-chunk-upload-session should be present in signed ID", chunkUploadSession);
        String blobSize = idAndMetadata.getSecond().get(RestUtils.Headers.BLOB_SIZE);
        assertNotNull("x-ambry-blob-size should be present in signed ID", blobSize);
        assertEquals("wrong size value in signed id", content.capacity(), Long.parseLong(blobSize));
        HttpHeaders expectedGetHeaders = new DefaultHttpHeaders().add(chunkUploadHeaders);
        // Use signed ID and blob ID for GET request
        expectedGetHeaders.add(RestUtils.Headers.BLOB_SIZE, content.capacity());
        // Blob TTL for chunk upload is fixed
        expectedGetHeaders.set(RestUtils.Headers.TTL, FRONTEND_CONFIG.chunkUploadInitialChunkTtlSecs);
        expectedGetHeaders.set(RestUtils.Headers.LIFE_VERSION, "0");
        for (String id : new String[] { signedId, idAndMetadata.getFirst() }) {
            getBlobAndVerify(id, null, GetOption.None, false, expectedGetHeaders, !container.isCacheable(), content, account.getName(), container.getName());
            getBlobInfoAndVerify(id, GetOption.None, expectedGetHeaders, !container.isCacheable(), account.getName(), container.getName(), null);
        }
        signedChunkIds.add(addClusterPrefix ? "/" + CLUSTER_NAME + signedId : signedId);
        fullContentStream.write(contentArray);
    }
    return new Pair<>(signedChunkIds, fullContentStream.toByteArray());
}
Also used : HttpHeaders(io.netty.handler.codec.http.HttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) ArrayList(java.util.ArrayList) HttpResponse(io.netty.handler.codec.http.HttpResponse) ResponseParts(com.github.ambry.rest.NettyClient.ResponseParts) ByteArrayOutputStream(java.io.ByteArrayOutputStream) URI(java.net.URI) ByteBuffer(java.nio.ByteBuffer) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) Map(java.util.Map) ClusterMap(com.github.ambry.clustermap.ClusterMap) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) Pair(com.github.ambry.utils.Pair)

Example 44 with Pair

use of com.github.ambry.utils.Pair in project ambry by linkedin.

the class SignedIdSerDe method fromJson.

/**
 * @param jsonString the JSON string to deserialize.
 * @return a {@link Pair} that contains the blob ID and additional metadata parsed from the JSON string.
 * @throws JSONException
 */
public static Pair<String, Map<String, String>> fromJson(String jsonString) throws JSONException {
    JSONObject jsonObject = new JSONObject(jsonString);
    String blobId = jsonObject.getString(BLOB_ID_FIELD);
    JSONObject metadataJson = jsonObject.optJSONObject(METADATA_FIELD);
    Map<String, String> metadata = new HashMap<>();
    if (metadataJson != null) {
        for (String key : metadataJson.keySet()) {
            metadata.put(key, metadataJson.getString(key));
        }
    }
    return new Pair<>(blobId, metadata);
}
Also used : JSONObject(org.json.JSONObject) HashMap(java.util.HashMap) Pair(com.github.ambry.utils.Pair)

Example 45 with Pair

use of com.github.ambry.utils.Pair in project ambry by linkedin.

the class StorageQuotaEnforcer method getQuotaAndUsage.

/**
 * Return quota and current usage for the account/container carried in the given {@code restRequest}.
 * If there is no account and container found in the {@code restRequest}, this method would return -1
 * for quota. If there is no quota found for the account/container, this method would return -1 for
 * quota as well.
 * @param restRequest the {@link RestRequest} that carries account and container in the header.
 * @return A {@link Pair} whose first element is quota the second element is current storage usage.
 */
Pair<Long, Long> getQuotaAndUsage(RestRequest restRequest) {
    long quotaValue = -1L;
    long currentUsage = 0L;
    try {
        Account account = RestUtils.getAccountFromArgs(restRequest.getArgs());
        Container container = RestUtils.getContainerFromArgs(restRequest.getArgs());
        QuotaResource quotaResource = account.getQuotaResourceType() == QuotaResourceType.ACCOUNT ? QuotaResource.fromAccount(account) : QuotaResource.fromContainer(container);
        quotaValue = getQuotaValueForResource(quotaResource);
        if (quotaValue != -1L) {
            currentUsage = storageUsages.getOrDefault(quotaResource, 0L);
        }
    } catch (Exception e) {
        logger.error("Failed to getQuotaAndUsage for RestRequest {}", restRequest, e);
    }
    return new Pair<>(quotaValue, currentUsage);
}
Also used : Account(com.github.ambry.account.Account) Container(com.github.ambry.account.Container) QuotaResource(com.github.ambry.quota.QuotaResource) QuotaException(com.github.ambry.quota.QuotaException) Pair(com.github.ambry.utils.Pair)

Aggregations

Pair (com.github.ambry.utils.Pair)64 ArrayList (java.util.ArrayList)29 HashMap (java.util.HashMap)28 Map (java.util.Map)28 Test (org.junit.Test)20 IOException (java.io.IOException)15 MetricRegistry (com.codahale.metrics.MetricRegistry)14 List (java.util.List)14 ByteBuffer (java.nio.ByteBuffer)13 Collections (java.util.Collections)13 File (java.io.File)12 Assert (org.junit.Assert)12 VerifiableProperties (com.github.ambry.config.VerifiableProperties)11 Utils (com.github.ambry.utils.Utils)10 HashSet (java.util.HashSet)10 Properties (java.util.Properties)10 Container (com.github.ambry.account.Container)9 TestUtils (com.github.ambry.utils.TestUtils)9 Arrays (java.util.Arrays)9 Set (java.util.Set)9