Search in sources :

Example 76 with Account

use of com.github.ambry.account.Account in project ambry by linkedin.

the class AccountAndContainerInjector method injectAccountAndContainerUsingServiceId.

/**
 * Inject {@link Account} and {@link Container} into a {@link RestRequest} based on a blob's service ID and
 * privacy setting.
 * @param restRequest The {@link RestRequest} to inject {@link Account} and {@link Container} object.
 * @param serviceId The service ID associated with the blob.
 * @param isPrivate The blob's privacy setting.
 * @param metricsGroup The {@link RestRequestMetricsGroup} to use to set up {@link ContainerMetrics}, or {@code null}
 *                     if {@link ContainerMetrics} instantiation is not needed.
 * @throws RestServiceException if either of {@link Account} or {@link Container} object could not be found.
 */
private void injectAccountAndContainerUsingServiceId(RestRequest restRequest, String serviceId, boolean isPrivate, RestRequestMetricsGroup metricsGroup) throws RestServiceException {
    // First, try to see if a migrated account exists for the service ID.
    Account targetAccount = accountService.getAccountByName(serviceId);
    if (targetAccount == null) {
        frontendMetrics.unrecognizedServiceIdCount.inc();
        logger.debug("Account cannot be found for put request with serviceId={}. Setting targetAccount to UNKNOWN_ACCOUNT", serviceId);
        // If a migrated account does not exist fall back to the UNKNOWN_ACCOUNT.
        targetAccount = accountService.getAccountById(Account.UNKNOWN_ACCOUNT_ID);
    }
    // Either the UNKNOWN_ACCOUNT, or the migrated account should contain default public/private containers
    Container targetContainer;
    short containerId = isPrivate ? Container.DEFAULT_PRIVATE_CONTAINER_ID : Container.DEFAULT_PUBLIC_CONTAINER_ID;
    try {
        targetContainer = accountService.getContainerById(targetAccount.getId(), containerId);
    } catch (AccountServiceException e) {
        throw new RestServiceException("Failed to get container with Id= " + containerId + " from account " + targetAccount.getName() + "for put request; ServiceId=" + serviceId + ", isPrivate=" + isPrivate, RestServiceErrorCode.getRestServiceErrorCode(e.getErrorCode()));
    }
    if (targetContainer == null) {
        throw new RestServiceException("Invalid account or container to inject; serviceId=" + serviceId + ", isPrivate=" + isPrivate, RestServiceErrorCode.InternalServerError);
    }
    setTargetAccountAndContainerInRestRequest(restRequest, targetAccount, targetContainer, metricsGroup);
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) Account(com.github.ambry.account.Account) AccountServiceException(com.github.ambry.account.AccountServiceException) Container(com.github.ambry.account.Container)

Example 77 with Account

use of com.github.ambry.account.Account in project ambry by linkedin.

the class AccountAndContainerInjector method injectAccountAndContainerUsingAccountAndContainerHeaders.

/**
 * Injects {@link Account} and {@link Container} for the PUT requests that carry the target account and container headers.
 * @param restRequest The {@link RestRequest} to inject {@link Account} and {@link Container} object.
 * @param metricsGroup The {@link RestRequestMetricsGroup} to use to set up {@link ContainerMetrics}, or {@code null}
 *                     if {@link ContainerMetrics} instantiation is not needed.
 * @throws RestServiceException if either of {@link Account} or {@link Container} object could not be found.
 */
private void injectAccountAndContainerUsingAccountAndContainerHeaders(RestRequest restRequest, RestRequestMetricsGroup metricsGroup) throws RestServiceException {
    String accountName = getHeader(restRequest.getArgs(), Headers.TARGET_ACCOUNT_NAME, false);
    Account targetAccount = accountService.getAccountByName(accountName);
    if (targetAccount == null) {
        frontendMetrics.unrecognizedAccountNameCount.inc();
        throw new RestServiceException("Account cannot be found for accountName=" + accountName + " in put request with account and container headers.", RestServiceErrorCode.InvalidAccount);
    }
    ensureAccountNameMatch(targetAccount, restRequest);
    String containerName = getHeader(restRequest.getArgs(), Headers.TARGET_CONTAINER_NAME, false);
    Container targetContainer;
    try {
        targetContainer = accountService.getContainerByName(accountName, containerName);
    } catch (AccountServiceException e) {
        throw new RestServiceException("Failed to get container " + containerName + " from account " + accountName + " for put request with account and container headers.", RestServiceErrorCode.getRestServiceErrorCode(e.getErrorCode()));
    }
    if (targetContainer == null) {
        frontendMetrics.unrecognizedContainerNameCount.inc();
        throw new RestServiceException("Container cannot be found for accountName=" + accountName + " and containerName=" + containerName + " in put request with account and container headers.", RestServiceErrorCode.InvalidContainer);
    }
    setTargetAccountAndContainerInRestRequest(restRequest, targetAccount, targetContainer, metricsGroup);
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) Account(com.github.ambry.account.Account) AccountServiceException(com.github.ambry.account.AccountServiceException) Container(com.github.ambry.account.Container)

Example 78 with Account

use of com.github.ambry.account.Account in project ambry by linkedin.

the class AmbrySecurityService method setAccountAndContainerHeaders.

/**
 * Adds the account and container details to the response headers if the {@code restRequest} contains the target
 * account and container and they are not generic unknowns.
 * @param restRequest the {@link RestRequest} that contains the {@link Account} and {@link Container} details.
 * @param restResponseChannel the {@link RestResponseChannel} where headers need to be set.
 * @throws RestServiceException if headers cannot be set.
 */
private void setAccountAndContainerHeaders(RestRequest restRequest, RestResponseChannel restResponseChannel) throws RestServiceException {
    Account account = RestUtils.getAccountFromArgs(restRequest.getArgs());
    Container container = RestUtils.getContainerFromArgs(restRequest.getArgs());
    if (account.getId() != Account.UNKNOWN_ACCOUNT_ID) {
        restResponseChannel.setHeader(RestUtils.Headers.TARGET_ACCOUNT_NAME, account.getName());
        restResponseChannel.setHeader(RestUtils.Headers.TARGET_CONTAINER_NAME, container.getName());
    }
    restResponseChannel.setHeader(RestUtils.Headers.PRIVATE, !container.isCacheable());
}
Also used : Account(com.github.ambry.account.Account) Container(com.github.ambry.account.Container)

Example 79 with Account

use of com.github.ambry.account.Account in project ambry by linkedin.

the class FrontendTestUrlSigningServiceFactory method injectionAccountAndContainerForGetHeadDeleteBlobIdTest.

/**
 * Tests injecting target {@link Account} and {@link Container} for GET/HEAD/DELETE blobId string in {@link BlobId#BLOB_ID_V2}.
 * The {@link AccountService} is prepopulated with a reference account and {@link InMemAccountService#UNKNOWN_ACCOUNT}. The expected
 * behavior should be:
 *
 * <pre>
 *   AId in blobId    CId in blobId     expected Error      injected account      injected container
 *    realAId           realCId          NotFound            refAccount            refContainer       This can succeed if the blob exists in backend.
 *    realAId           UNKNOWN          InvalidContainer    null                  null
 *    realAId           nonExistCId      InvalidContainer    null                  null
 *    UNKNOWN           realCId          InvalidContainer    null                  null
 *    UNKNOWN           UNKNOWN          NotFound            UNKNOWN               UNKNOWN            This can succeed if the blob exists in backend.
 *    UNKNOWN           nonExistCId      InvalidContainer    null                  null
 *    nonExistAId       realCId          InvalidAccount      null                  null
 *    nonExistAId       UNKNOWN          InvalidAccount      null                  null
 *    nonExistAId       nonExistCId      InvalidAccount      null                  null
 * </pre>
 *
 * @throws Exception
 */
@Test
public void injectionAccountAndContainerForGetHeadDeleteBlobIdTest() throws Exception {
    List<Short> blobIdVersions = Arrays.stream(BlobId.getAllValidVersions()).filter(version -> version >= BlobId.BLOB_ID_V2).collect(Collectors.toList());
    for (short version : blobIdVersions) {
        populateAccountService();
        // aid=refAId, cid=refCId
        String blobId = new BlobId(version, BlobId.BlobIdType.NATIVE, ClusterMap.UNKNOWN_DATACENTER_ID, refAccount.getId(), refContainer.getId(), clusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS).get(0), false, BlobId.BlobDataType.DATACHUNK).getID();
        verifyAccountAndContainerFromBlobId(blobId, refAccount, refContainer, RestServiceErrorCode.NotFound);
        // aid=refAId, cid=unknownCId
        blobId = new BlobId(version, BlobId.BlobIdType.NATIVE, ClusterMap.UNKNOWN_DATACENTER_ID, refAccount.getId(), Container.UNKNOWN_CONTAINER_ID, clusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS).get(0), false, BlobId.BlobDataType.DATACHUNK).getID();
        verifyAccountAndContainerFromBlobId(blobId, null, null, RestServiceErrorCode.InvalidContainer);
        // aid=refAId, cid=nonExistCId
        blobId = new BlobId(version, BlobId.BlobIdType.NATIVE, ClusterMap.UNKNOWN_DATACENTER_ID, refAccount.getId(), (short) -1234, clusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS).get(0), false, BlobId.BlobDataType.DATACHUNK).getID();
        verifyAccountAndContainerFromBlobId(blobId, null, null, RestServiceErrorCode.InvalidContainer);
        // aid=unknownAId, cid=refCId
        blobId = new BlobId(version, BlobId.BlobIdType.NATIVE, ClusterMap.UNKNOWN_DATACENTER_ID, Account.UNKNOWN_ACCOUNT_ID, refContainer.getId(), clusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS).get(0), false, BlobId.BlobDataType.DATACHUNK).getID();
        verifyAccountAndContainerFromBlobId(blobId, null, null, RestServiceErrorCode.InvalidContainer);
        // aid=unknownAId, cid=unknownCId
        blobId = new BlobId(version, BlobId.BlobIdType.NATIVE, ClusterMap.UNKNOWN_DATACENTER_ID, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, clusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS).get(0), false, BlobId.BlobDataType.DATACHUNK).getID();
        verifyAccountAndContainerFromBlobId(blobId, InMemAccountService.UNKNOWN_ACCOUNT, Container.UNKNOWN_CONTAINER, RestServiceErrorCode.NotFound);
        // aid=unknownAId, cid=nonExistCId
        blobId = new BlobId(version, BlobId.BlobIdType.NATIVE, ClusterMap.UNKNOWN_DATACENTER_ID, Account.UNKNOWN_ACCOUNT_ID, (short) -1234, clusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS).get(0), false, BlobId.BlobDataType.DATACHUNK).getID();
        verifyAccountAndContainerFromBlobId(blobId, null, null, RestServiceErrorCode.InvalidContainer);
        // aid=nonExistAId, cid=refCId
        blobId = new BlobId(version, BlobId.BlobIdType.NATIVE, ClusterMap.UNKNOWN_DATACENTER_ID, (short) -1234, refContainer.getId(), clusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS).get(0), false, BlobId.BlobDataType.DATACHUNK).getID();
        verifyAccountAndContainerFromBlobId(blobId, null, null, RestServiceErrorCode.InvalidAccount);
        // aid=nonExistAId, cid=unknownCId
        blobId = new BlobId(version, BlobId.BlobIdType.NATIVE, ClusterMap.UNKNOWN_DATACENTER_ID, (short) -1234, Container.UNKNOWN_CONTAINER_ID, clusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS).get(0), false, BlobId.BlobDataType.DATACHUNK).getID();
        verifyAccountAndContainerFromBlobId(blobId, null, null, RestServiceErrorCode.InvalidAccount);
        // aid=nonExistAId, cid=nonExistCId
        blobId = new BlobId(version, BlobId.BlobIdType.NATIVE, ClusterMap.UNKNOWN_DATACENTER_ID, (short) -1234, (short) -11, clusterMap.getWritablePartitionIds(MockClusterMap.DEFAULT_PARTITION_CLASS).get(0), false, BlobId.BlobDataType.DATACHUNK).getID();
        verifyAccountAndContainerFromBlobId(blobId, null, null, RestServiceErrorCode.InvalidAccount);
    }
}
Also used : GetOption(com.github.ambry.protocol.GetOption) MockRestRequest(com.github.ambry.rest.MockRestRequest) Arrays(java.util.Arrays) FrontendConfig(com.github.ambry.config.FrontendConfig) AggregatedPartitionClassStorageStats(com.github.ambry.server.storagestats.AggregatedPartitionClassStorageStats) BlobProperties(com.github.ambry.messageformat.BlobProperties) FutureResult(com.github.ambry.router.FutureResult) Future(java.util.concurrent.Future) JSONException(org.json.JSONException) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) ChunkInfo(com.github.ambry.router.ChunkInfo) EnumSet(java.util.EnumSet) RouterErrorCode(com.github.ambry.router.RouterErrorCode) RestResponseHandler(com.github.ambry.rest.RestResponseHandler) ReadableStreamChannel(com.github.ambry.router.ReadableStreamChannel) ClusterMapSnapshotConstants(com.github.ambry.clustermap.ClusterMapSnapshotConstants) RestResponseChannel(com.github.ambry.rest.RestResponseChannel) Set(java.util.Set) StandardCharsets(java.nio.charset.StandardCharsets) AccountStatsStore(com.github.ambry.accountstats.AccountStatsStore) BlobInfo(com.github.ambry.messageformat.BlobInfo) InvocationTargetException(java.lang.reflect.InvocationTargetException) AggregatedAccountStorageStats(com.github.ambry.server.storagestats.AggregatedAccountStorageStats) CountDownLatch(java.util.concurrent.CountDownLatch) RestServiceException(com.github.ambry.rest.RestServiceException) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) Account(com.github.ambry.account.Account) InMemoryRouter(com.github.ambry.router.InMemoryRouter) SimpleDateFormat(java.text.SimpleDateFormat) RestTestUtils(com.github.ambry.rest.RestTestUtils) PutBlobOptions(com.github.ambry.router.PutBlobOptions) ArrayList(java.util.ArrayList) QuotaConfig(com.github.ambry.config.QuotaConfig) QuotaMode(com.github.ambry.quota.QuotaMode) Lists(com.google.common.collect.Lists) SSLSession(javax.net.ssl.SSLSession) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) SystemTime(com.github.ambry.utils.SystemTime) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) RestMethod(com.github.ambry.rest.RestMethod) VerifiableProperties(com.github.ambry.config.VerifiableProperties) IOException(java.io.IOException) Test(org.junit.Test) RouterException(com.github.ambry.router.RouterException) InMemAccountServiceFactory(com.github.ambry.account.InMemAccountServiceFactory) AmbryQuotaManager(com.github.ambry.quota.AmbryQuotaManager) QuotaMetrics(com.github.ambry.quota.QuotaMetrics) GetBlobResult(com.github.ambry.router.GetBlobResult) PutBlobOptionsBuilder(com.github.ambry.router.PutBlobOptionsBuilder) SimpleQuotaRecommendationMergePolicy(com.github.ambry.quota.SimpleQuotaRecommendationMergePolicy) Assert(org.junit.Assert) Date(java.util.Date) URISyntaxException(java.net.URISyntaxException) ResponseStatus(com.github.ambry.rest.ResponseStatus) ByteBufferReadableStreamChannel(com.github.ambry.commons.ByteBufferReadableStreamChannel) ContainerBuilder(com.github.ambry.account.ContainerBuilder) ByteBuffer(java.nio.ByteBuffer) AccountCollectionSerde(com.github.ambry.account.AccountCollectionSerde) RestUtilsTest(com.github.ambry.rest.RestUtilsTest) JSONObject(org.json.JSONObject) ByteArrayInputStream(java.io.ByteArrayInputStream) Locale(java.util.Locale) After(org.junit.After) Method(java.lang.reflect.Method) Container(com.github.ambry.account.Container) TimeZone(java.util.TimeZone) RestServiceErrorCode(com.github.ambry.rest.RestServiceErrorCode) Utils(com.github.ambry.utils.Utils) AccountBuilder(com.github.ambry.account.AccountBuilder) Collectors(java.util.stream.Collectors) NamedBlobRecord(com.github.ambry.named.NamedBlobRecord) AsyncWritableChannel(com.github.ambry.router.AsyncWritableChannel) List(java.util.List) QuotaTestUtils(com.github.ambry.quota.QuotaTestUtils) RestRequestMetricsTracker(com.github.ambry.rest.RestRequestMetricsTracker) Callback(com.github.ambry.commons.Callback) RestUtils(com.github.ambry.rest.RestUtils) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InMemAccountService(com.github.ambry.account.InMemAccountService) PartitionId(com.github.ambry.clustermap.PartitionId) BlobId(com.github.ambry.commons.BlobId) StorageStatsUtilTest(com.github.ambry.server.StorageStatsUtilTest) ByteRanges(com.github.ambry.router.ByteRanges) AccountService(com.github.ambry.account.AccountService) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) QuotaManager(com.github.ambry.quota.QuotaManager) HashSet(java.util.HashSet) NamedBlobDb(com.github.ambry.named.NamedBlobDb) CommonTestUtils(com.github.ambry.commons.CommonTestUtils) LinkedList(java.util.LinkedList) Router(com.github.ambry.router.Router) Pair(com.github.ambry.utils.Pair) Iterator(java.util.Iterator) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) QuotaChargeCallback(com.github.ambry.quota.QuotaChargeCallback) ByteRange(com.github.ambry.router.ByteRange) ClusterMap(com.github.ambry.clustermap.ClusterMap) GetBlobOptions(com.github.ambry.router.GetBlobOptions) AccountServiceException(com.github.ambry.account.AccountServiceException) TimeUnit(java.util.concurrent.TimeUnit) Mockito(org.mockito.Mockito) StatsReportType(com.github.ambry.server.StatsReportType) RestRequest(com.github.ambry.rest.RestRequest) Collections(java.util.Collections) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) BlobId(com.github.ambry.commons.BlobId) Test(org.junit.Test) RestUtilsTest(com.github.ambry.rest.RestUtilsTest) StorageStatsUtilTest(com.github.ambry.server.StorageStatsUtilTest)

Example 80 with Account

use of com.github.ambry.account.Account in project ambry by linkedin.

the class AmbrySecurityServiceTest method processRequestTest.

/**
 * Tests {@link AmbrySecurityService#processRequest(RestRequest, Callback)} for common as well as uncommon cases
 * @throws Exception
 */
@Test
public void processRequestTest() throws Exception {
    // rest request being null
    TestUtils.assertException(IllegalArgumentException.class, () -> securityService.preProcessRequest(null).get(), null);
    TestUtils.assertException(IllegalArgumentException.class, () -> securityService.processRequest(null).get(), null);
    TestUtils.assertException(IllegalArgumentException.class, () -> securityService.postProcessRequest(null).get(), null);
    // without callbacks
    RestMethod[] methods = new RestMethod[] { RestMethod.POST, RestMethod.GET, RestMethod.DELETE, RestMethod.HEAD, RestMethod.OPTIONS, RestMethod.PUT };
    for (RestMethod restMethod : methods) {
        RestRequest restRequest = createRestRequest(restMethod, "/", null);
        securityService.preProcessRequest(restRequest).get();
        securityService.processRequest(restRequest).get();
        securityService.postProcessRequest(restRequest).get();
    }
    // with GET sub resources
    for (RestUtils.SubResource subResource : RestUtils.SubResource.values()) {
        RestRequest restRequest = createRestRequest(RestMethod.GET, "/sampleId/" + subResource, null);
        Account account = InMemAccountService.UNKNOWN_ACCOUNT;
        insertAccountAndContainer(restRequest, account, account.getContainerById(Container.UNKNOWN_CONTAINER_ID));
        securityService.preProcessRequest(restRequest).get();
        securityService.processRequest(restRequest).get();
        securityService.postProcessRequest(restRequest).get();
    }
    // with UrlSigningService denying the request
    URL_SIGNING_SERVICE_FACTORY.isRequestSigned = true;
    URL_SIGNING_SERVICE_FACTORY.verifySignedRequestException = new RestServiceException("Msg", RestServiceErrorCode.Unauthorized);
    testExceptionCasesProcessRequest(createRestRequest(RestMethod.GET, "/", null), RestServiceErrorCode.Unauthorized, false);
    URL_SIGNING_SERVICE_FACTORY.isRequestSigned = false;
    // security service closed
    securityService.close();
    for (RestMethod restMethod : methods) {
        testExceptionCasesProcessRequest(createRestRequest(restMethod, "/", null), RestServiceErrorCode.ServiceUnavailable, true);
    }
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) Account(com.github.ambry.account.Account) MockRestRequest(com.github.ambry.rest.MockRestRequest) RestRequest(com.github.ambry.rest.RestRequest) RestUtils(com.github.ambry.rest.RestUtils) RestMethod(com.github.ambry.rest.RestMethod) Test(org.junit.Test)

Aggregations

Account (com.github.ambry.account.Account)114 Container (com.github.ambry.account.Container)87 Test (org.junit.Test)67 RestServiceException (com.github.ambry.rest.RestServiceException)24 ArrayList (java.util.ArrayList)22 RestRequest (com.github.ambry.rest.RestRequest)18 JSONObject (org.json.JSONObject)18 MockRestRequest (com.github.ambry.rest.MockRestRequest)17 VerifiableProperties (com.github.ambry.config.VerifiableProperties)16 HashMap (java.util.HashMap)15 HashSet (java.util.HashSet)15 AccountBuilder (com.github.ambry.account.AccountBuilder)14 MockRestResponseChannel (com.github.ambry.rest.MockRestResponseChannel)14 ContainerBuilder (com.github.ambry.account.ContainerBuilder)13 Properties (java.util.Properties)13 MetricRegistry (com.codahale.metrics.MetricRegistry)12 InMemAccountService (com.github.ambry.account.InMemAccountService)12 ByteBuffer (java.nio.ByteBuffer)12 RestMethod (com.github.ambry.rest.RestMethod)11 Map (java.util.Map)11