@Test public void processResponseTest() throws Exception { RestRequest restRequest = createRestRequest(RestMethod.GET, "/", null); TestUtils.assertException(IllegalArgumentException.class, () -> securityService.processResponse(null, new MockRestResponseChannel(), DEFAULT_INFO).get(), null); TestUtils.assertException(IllegalArgumentException.class, () -> securityService.processResponse(restRequest, null, DEFAULT_INFO).get(), null); TestUtils.assertException(IllegalArgumentException.class, () -> securityService.processResponse(restRequest, new MockRestResponseChannel(), null).get(), null); RestMethod[] methods = {RestMethod.DELETE}; for (RestMethod restMethod : methods) { testExceptionCasesProcessResponse(restMethod, new MockRestResponseChannel(), DEFAULT_INFO, RestServiceErrorCode.InternalServerError); } securityService.processResponse(createRestRequest(RestMethod.OPTIONS, "/", null), new MockRestResponseChannel(), null).get(); securityService.processResponse(createRestRequest(RestMethod.PUT, "/", null), new MockRestResponseChannel(), null) .get(); securityService.processResponse(createRestRequest(RestMethod.GET, Operations.GET_SIGNED_URL, null), new MockRestResponseChannel(), null).get(); testHeadBlobWithVariousRanges(DEFAULT_INFO); testHeadBlobWithVariousRanges(LIFEVERSION_INFO); testHeadBlobWithVariousRanges(UNKNOWN_INFO); testHeadBlobWithVariousRanges(UNKNOWN_INFO_ENC); BlobInfo blobInfo = new BlobInfo( new BlobProperties(100, SERVICE_ID, null, "image/gif", false, Utils.Infinite_Time, REF_ACCOUNT.getId(), REF_CONTAINER.getId(), false, null), new byte[0]); testHeadBlobWithVariousRanges(blobInfo); blobInfo = new BlobInfo( new BlobProperties(100, SERVICE_ID, OWNER_ID, null, false, Utils.Infinite_Time, REF_ACCOUNT.getId(), REF_CONTAINER.getId(), false, null), new byte[0]); testHeadBlobWithVariousRanges(blobInfo); blobInfo = new BlobInfo( new BlobProperties(100, SERVICE_ID, OWNER_ID, "image/gif", false, 10000, REF_ACCOUNT.getId(), REF_CONTAINER.getId(), false, null), new byte[0]); testHeadBlobWithVariousRanges(blobInfo); testGetSubResource(DEFAULT_INFO, RestUtils.SubResource.BlobInfo); testGetSubResource(LIFEVERSION_INFO, RestUtils.SubResource.BlobInfo); testGetSubResource(UNKNOWN_INFO, RestUtils.SubResource.BlobInfo); testGetSubResource(UNKNOWN_INFO, RestUtils.SubResource.BlobInfo); testGetSubResource(UNKNOWN_INFO_ENC, RestUtils.SubResource.BlobInfo); testGetSubResource(DEFAULT_INFO, RestUtils.SubResource.UserMetadata); byte[] usermetadata = TestUtils.getRandomBytes(10); testGetSubResource(new BlobInfo(DEFAULT_INFO.getBlobProperties(), usermetadata), RestUtils.SubResource.UserMetadata); testPostBlob(); testGetBlobWithVariousRanges(LIFEVERSION_INFO); blobInfo = new BlobInfo( new BlobProperties(FRONTEND_CONFIG.chunkedGetResponseThresholdInBytes - 1, SERVICE_ID, OWNER_ID, "image/gif", false, 10000, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, false, null), new byte[0]); testGetBlobWithVariousRanges(blobInfo); blobInfo = new BlobInfo( new BlobProperties(FRONTEND_CONFIG.chunkedGetResponseThresholdInBytes, SERVICE_ID, OWNER_ID, "image/gif", false, 10000, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, false, null), new byte[0]); testGetBlobWithVariousRanges(blobInfo); blobInfo = new BlobInfo( new BlobProperties(FRONTEND_CONFIG.chunkedGetResponseThresholdInBytes * 2, SERVICE_ID, OWNER_ID, "image/gif", false, 10000, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, false, null), new byte[0]); testGetBlobWithVariousRanges(blobInfo); blobInfo = new BlobInfo(new BlobProperties(100, SERVICE_ID, OWNER_ID, null, true, 10000, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, false, null), new byte[0]); testGetBlobWithVariousRanges(blobInfo); blobInfo = new BlobInfo(new BlobProperties(100, SERVICE_ID, OWNER_ID, "image/gif", false, Utils.Infinite_Time, Account.UNKNOWN_ACCOUNT_ID, Container.DEFAULT_PRIVATE_CONTAINER_ID, false, null), new byte[0]); testGetBlobWithVariousRanges(blobInfo); blobInfo = new BlobInfo(new BlobProperties(100, SERVICE_ID, OWNER_ID, "image/gif", true, Utils.Infinite_Time, Account.UNKNOWN_ACCOUNT_ID, Container.DEFAULT_PUBLIC_CONTAINER_ID, false, null), new byte[0]); testGetBlobWithVariousRanges(blobInfo); testGetNotModifiedBlob(blobInfo, blobInfo.getBlobProperties().getCreationTimeInMs() + 1000); testGetNotModifiedBlob(blobInfo, blobInfo.getBlobProperties().getCreationTimeInMs()); testGetNotModifiedBlob(blobInfo, blobInfo.getBlobProperties().getCreationTimeInMs() - 1000); blobInfo = new BlobInfo( new BlobProperties(100, SERVICE_ID, OWNER_ID, "text/html", true, 10000, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, false, null), new byte[0]); testGetBlobWithVariousRanges(blobInfo); testGetNotModifiedBlob(DEFAULT_INFO, DEFAULT_INFO.getBlobProperties().getCreationTimeInMs() + 1000); testGetNotModifiedBlob(DEFAULT_INFO, DEFAULT_INFO.getBlobProperties().getCreationTimeInMs()); testGetNotModifiedBlob(DEFAULT_INFO, DEFAULT_INFO.getBlobProperties().getCreationTimeInMs() - 1000); testExceptionCasesProcessResponse(RestMethod.HEAD, new BadRestResponseChannel(), blobInfo, RestServiceErrorCode.InternalServerError); testExceptionCasesProcessResponse(RestMethod.GET, new BadRestResponseChannel(), blobInfo, RestServiceErrorCode.InternalServerError); testExceptionCasesProcessResponse(RestMethod.POST, new BadRestResponseChannel(), blobInfo, RestServiceErrorCode.InternalServerError); securityService.close(); methods = new RestMethod[]{RestMethod.POST, RestMethod.GET, RestMethod.DELETE, RestMethod.HEAD}; for (RestMethod restMethod : methods) { testExceptionCasesProcessResponse(restMethod, new MockRestResponseChannel(), blobInfo, RestServiceErrorCode.ServiceUnavailable); } }
@Override public void processResponse(RestRequest restRequest, RestResponseChannel responseChannel, BlobInfo blobInfo, Callback<Void> callback) { Exception exception = null; frontendMetrics.securityServiceProcessResponseRate.mark(); long startTimeMs = System.currentTimeMillis(); if (!isOpen) { exception = new RestServiceException("SecurityService is closed", RestServiceErrorCode.ServiceUnavailable); } else { if (restRequest == null || responseChannel == null) { throw new IllegalArgumentException("One of the required params is null"); } RequestPath requestPath = RestUtils.getRequestPath(restRequest); RestMethod restMethod = restRequest.getRestMethod(); if (blobInfo == null && !restMethod.equals(RestMethod.OPTIONS) && !restMethod.equals(RestMethod.PUT)) { if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) { throw new IllegalArgumentException("BlobInfo is null"); } } try { GetBlobOptions options; responseChannel.setHeader(RestUtils.Headers.DATE, new GregorianCalendar().getTime()); switch (restMethod) { case HEAD: options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, NO_BLOB_SEGMENT_IDX_SPECIFIED); responseChannel.setStatus(options.getRange() == null ? ResponseStatus.Ok : ResponseStatus.PartialContent); responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); setHeadResponseHeaders(blobInfo, options, restRequest, responseChannel); break; case GET: if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) { options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, NO_BLOB_SEGMENT_IDX_SPECIFIED); responseChannel.setStatus(ResponseStatus.Ok); RestUtils.SubResource subResource = RestUtils.getRequestPath(restRequest).getSubResource(); responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); if (subResource == null) { Long ifModifiedSinceMs = getIfModifiedSinceMs(restRequest); if (ifModifiedSinceMs != null && RestUtils.toSecondsPrecisionInMs(blobInfo.getBlobProperties().getCreationTimeInMs()) <= ifModifiedSinceMs) { responseChannel.setStatus(ResponseStatus.NotModified); } else { if (options.getRange() != null) { responseChannel.setStatus(ResponseStatus.PartialContent); } setGetBlobResponseHeaders(blobInfo, options, responseChannel); setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel); responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion()); } setCacheHeaders(restRequest, responseChannel); } else { if (subResource.equals(RestUtils.SubResource.BlobInfo)) { setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion()); } else if (subResource.equals(SubResource.Segment)) { setGetBlobResponseHeaders(blobInfo, options, responseChannel); setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); } if (!setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel)) { restRequest.setArg(InternalKeys.SEND_USER_METADATA_AS_RESPONSE_BODY, true); } } } break; case POST: responseChannel.setStatus(ResponseStatus.Created); responseChannel.setHeader(RestUtils.Headers.CONTENT_LENGTH, 0); responseChannel.setHeader(RestUtils.Headers.CREATION_TIME, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); break; case OPTIONS: case PUT: break; default: exception = new RestServiceException("Cannot process response for request with method " + restMethod, RestServiceErrorCode.InternalServerError); } } catch (RestServiceException e) { exception = e; } } frontendMetrics.securityServiceProcessResponseTimeInMs.update(System.currentTimeMillis() - startTimeMs); callback.onCompletion(null, exception); }
AmbrySecurityService implements SecurityService { @Override public void processResponse(RestRequest restRequest, RestResponseChannel responseChannel, BlobInfo blobInfo, Callback<Void> callback) { Exception exception = null; frontendMetrics.securityServiceProcessResponseRate.mark(); long startTimeMs = System.currentTimeMillis(); if (!isOpen) { exception = new RestServiceException("SecurityService is closed", RestServiceErrorCode.ServiceUnavailable); } else { if (restRequest == null || responseChannel == null) { throw new IllegalArgumentException("One of the required params is null"); } RequestPath requestPath = RestUtils.getRequestPath(restRequest); RestMethod restMethod = restRequest.getRestMethod(); if (blobInfo == null && !restMethod.equals(RestMethod.OPTIONS) && !restMethod.equals(RestMethod.PUT)) { if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) { throw new IllegalArgumentException("BlobInfo is null"); } } try { GetBlobOptions options; responseChannel.setHeader(RestUtils.Headers.DATE, new GregorianCalendar().getTime()); switch (restMethod) { case HEAD: options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, NO_BLOB_SEGMENT_IDX_SPECIFIED); responseChannel.setStatus(options.getRange() == null ? ResponseStatus.Ok : ResponseStatus.PartialContent); responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); setHeadResponseHeaders(blobInfo, options, restRequest, responseChannel); break; case GET: if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) { options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, NO_BLOB_SEGMENT_IDX_SPECIFIED); responseChannel.setStatus(ResponseStatus.Ok); RestUtils.SubResource subResource = RestUtils.getRequestPath(restRequest).getSubResource(); responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); if (subResource == null) { Long ifModifiedSinceMs = getIfModifiedSinceMs(restRequest); if (ifModifiedSinceMs != null && RestUtils.toSecondsPrecisionInMs(blobInfo.getBlobProperties().getCreationTimeInMs()) <= ifModifiedSinceMs) { responseChannel.setStatus(ResponseStatus.NotModified); } else { if (options.getRange() != null) { responseChannel.setStatus(ResponseStatus.PartialContent); } setGetBlobResponseHeaders(blobInfo, options, responseChannel); setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel); responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion()); } setCacheHeaders(restRequest, responseChannel); } else { if (subResource.equals(RestUtils.SubResource.BlobInfo)) { setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion()); } else if (subResource.equals(SubResource.Segment)) { setGetBlobResponseHeaders(blobInfo, options, responseChannel); setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); } if (!setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel)) { restRequest.setArg(InternalKeys.SEND_USER_METADATA_AS_RESPONSE_BODY, true); } } } break; case POST: responseChannel.setStatus(ResponseStatus.Created); responseChannel.setHeader(RestUtils.Headers.CONTENT_LENGTH, 0); responseChannel.setHeader(RestUtils.Headers.CREATION_TIME, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); break; case OPTIONS: case PUT: break; default: exception = new RestServiceException("Cannot process response for request with method " + restMethod, RestServiceErrorCode.InternalServerError); } } catch (RestServiceException e) { exception = e; } } frontendMetrics.securityServiceProcessResponseTimeInMs.update(System.currentTimeMillis() - startTimeMs); callback.onCompletion(null, exception); } }
AmbrySecurityService implements SecurityService { @Override public void processResponse(RestRequest restRequest, RestResponseChannel responseChannel, BlobInfo blobInfo, Callback<Void> callback) { Exception exception = null; frontendMetrics.securityServiceProcessResponseRate.mark(); long startTimeMs = System.currentTimeMillis(); if (!isOpen) { exception = new RestServiceException("SecurityService is closed", RestServiceErrorCode.ServiceUnavailable); } else { if (restRequest == null || responseChannel == null) { throw new IllegalArgumentException("One of the required params is null"); } RequestPath requestPath = RestUtils.getRequestPath(restRequest); RestMethod restMethod = restRequest.getRestMethod(); if (blobInfo == null && !restMethod.equals(RestMethod.OPTIONS) && !restMethod.equals(RestMethod.PUT)) { if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) { throw new IllegalArgumentException("BlobInfo is null"); } } try { GetBlobOptions options; responseChannel.setHeader(RestUtils.Headers.DATE, new GregorianCalendar().getTime()); switch (restMethod) { case HEAD: options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, NO_BLOB_SEGMENT_IDX_SPECIFIED); responseChannel.setStatus(options.getRange() == null ? ResponseStatus.Ok : ResponseStatus.PartialContent); responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); setHeadResponseHeaders(blobInfo, options, restRequest, responseChannel); break; case GET: if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) { options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, NO_BLOB_SEGMENT_IDX_SPECIFIED); responseChannel.setStatus(ResponseStatus.Ok); RestUtils.SubResource subResource = RestUtils.getRequestPath(restRequest).getSubResource(); responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); if (subResource == null) { Long ifModifiedSinceMs = getIfModifiedSinceMs(restRequest); if (ifModifiedSinceMs != null && RestUtils.toSecondsPrecisionInMs(blobInfo.getBlobProperties().getCreationTimeInMs()) <= ifModifiedSinceMs) { responseChannel.setStatus(ResponseStatus.NotModified); } else { if (options.getRange() != null) { responseChannel.setStatus(ResponseStatus.PartialContent); } setGetBlobResponseHeaders(blobInfo, options, responseChannel); setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel); responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion()); } setCacheHeaders(restRequest, responseChannel); } else { if (subResource.equals(RestUtils.SubResource.BlobInfo)) { setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion()); } else if (subResource.equals(SubResource.Segment)) { setGetBlobResponseHeaders(blobInfo, options, responseChannel); setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); } if (!setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel)) { restRequest.setArg(InternalKeys.SEND_USER_METADATA_AS_RESPONSE_BODY, true); } } } break; case POST: responseChannel.setStatus(ResponseStatus.Created); responseChannel.setHeader(RestUtils.Headers.CONTENT_LENGTH, 0); responseChannel.setHeader(RestUtils.Headers.CREATION_TIME, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); break; case OPTIONS: case PUT: break; default: exception = new RestServiceException("Cannot process response for request with method " + restMethod, RestServiceErrorCode.InternalServerError); } } catch (RestServiceException e) { exception = e; } } frontendMetrics.securityServiceProcessResponseTimeInMs.update(System.currentTimeMillis() - startTimeMs); callback.onCompletion(null, exception); } AmbrySecurityService(FrontendConfig frontendConfig, FrontendMetrics frontendMetrics,
      UrlSigningService urlSigningService, QuotaManager quotaManager); }
AmbrySecurityService implements SecurityService { @Override public void processResponse(RestRequest restRequest, RestResponseChannel responseChannel, BlobInfo blobInfo, Callback<Void> callback) { Exception exception = null; frontendMetrics.securityServiceProcessResponseRate.mark(); long startTimeMs = System.currentTimeMillis(); if (!isOpen) { exception = new RestServiceException("SecurityService is closed", RestServiceErrorCode.ServiceUnavailable); } else { if (restRequest == null || responseChannel == null) { throw new IllegalArgumentException("One of the required params is null"); } RequestPath requestPath = RestUtils.getRequestPath(restRequest); RestMethod restMethod = restRequest.getRestMethod(); if (blobInfo == null && !restMethod.equals(RestMethod.OPTIONS) && !restMethod.equals(RestMethod.PUT)) { if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) { throw new IllegalArgumentException("BlobInfo is null"); } } try { GetBlobOptions options; responseChannel.setHeader(RestUtils.Headers.DATE, new GregorianCalendar().getTime()); switch (restMethod) { case HEAD: options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, NO_BLOB_SEGMENT_IDX_SPECIFIED); responseChannel.setStatus(options.getRange() == null ? ResponseStatus.Ok : ResponseStatus.PartialContent); responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); setHeadResponseHeaders(blobInfo, options, restRequest, responseChannel); break; case GET: if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) { options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, NO_BLOB_SEGMENT_IDX_SPECIFIED); responseChannel.setStatus(ResponseStatus.Ok); RestUtils.SubResource subResource = RestUtils.getRequestPath(restRequest).getSubResource(); responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); if (subResource == null) { Long ifModifiedSinceMs = getIfModifiedSinceMs(restRequest); if (ifModifiedSinceMs != null && RestUtils.toSecondsPrecisionInMs(blobInfo.getBlobProperties().getCreationTimeInMs()) <= ifModifiedSinceMs) { responseChannel.setStatus(ResponseStatus.NotModified); } else { if (options.getRange() != null) { responseChannel.setStatus(ResponseStatus.PartialContent); } setGetBlobResponseHeaders(blobInfo, options, responseChannel); setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel); responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion()); } setCacheHeaders(restRequest, responseChannel); } else { if (subResource.equals(RestUtils.SubResource.BlobInfo)) { setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion()); } else if (subResource.equals(SubResource.Segment)) { setGetBlobResponseHeaders(blobInfo, options, responseChannel); setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); } if (!setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel)) { restRequest.setArg(InternalKeys.SEND_USER_METADATA_AS_RESPONSE_BODY, true); } } } break; case POST: responseChannel.setStatus(ResponseStatus.Created); responseChannel.setHeader(RestUtils.Headers.CONTENT_LENGTH, 0); responseChannel.setHeader(RestUtils.Headers.CREATION_TIME, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); break; case OPTIONS: case PUT: break; default: exception = new RestServiceException("Cannot process response for request with method " + restMethod, RestServiceErrorCode.InternalServerError); } } catch (RestServiceException e) { exception = e; } } frontendMetrics.securityServiceProcessResponseTimeInMs.update(System.currentTimeMillis() - startTimeMs); callback.onCompletion(null, exception); } AmbrySecurityService(FrontendConfig frontendConfig, FrontendMetrics frontendMetrics,
      UrlSigningService urlSigningService, QuotaManager quotaManager); @Override void preProcessRequest(RestRequest restRequest, Callback<Void> callback); @Override void processRequest(RestRequest restRequest, Callback<Void> callback); @Override void postProcessRequest(RestRequest restRequest, Callback<Void> callback); @Override void processResponse(RestRequest restRequest, RestResponseChannel responseChannel, BlobInfo blobInfo,
      Callback<Void> callback); @Override void close(); }
AmbrySecurityService implements SecurityService { @Override public void processResponse(RestRequest restRequest, RestResponseChannel responseChannel, BlobInfo blobInfo, Callback<Void> callback) { Exception exception = null; frontendMetrics.securityServiceProcessResponseRate.mark(); long startTimeMs = System.currentTimeMillis(); if (!isOpen) { exception = new RestServiceException("SecurityService is closed", RestServiceErrorCode.ServiceUnavailable); } else { if (restRequest == null || responseChannel == null) { throw new IllegalArgumentException("One of the required params is null"); } RequestPath requestPath = RestUtils.getRequestPath(restRequest); RestMethod restMethod = restRequest.getRestMethod(); if (blobInfo == null && !restMethod.equals(RestMethod.OPTIONS) && !restMethod.equals(RestMethod.PUT)) { if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) { throw new IllegalArgumentException("BlobInfo is null"); } } try { GetBlobOptions options; responseChannel.setHeader(RestUtils.Headers.DATE, new GregorianCalendar().getTime()); switch (restMethod) { case HEAD: options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, NO_BLOB_SEGMENT_IDX_SPECIFIED); responseChannel.setStatus(options.getRange() == null ? ResponseStatus.Ok : ResponseStatus.PartialContent); responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); setHeadResponseHeaders(blobInfo, options, restRequest, responseChannel); break; case GET: if (!requestPath.matchesOperation(Operations.GET_SIGNED_URL)) { options = RestUtils.buildGetBlobOptions(restRequest.getArgs(), null, GetOption.None, NO_BLOB_SEGMENT_IDX_SPECIFIED); responseChannel.setStatus(ResponseStatus.Ok); RestUtils.SubResource subResource = RestUtils.getRequestPath(restRequest).getSubResource(); responseChannel.setHeader(RestUtils.Headers.LAST_MODIFIED, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); if (subResource == null) { Long ifModifiedSinceMs = getIfModifiedSinceMs(restRequest); if (ifModifiedSinceMs != null && RestUtils.toSecondsPrecisionInMs(blobInfo.getBlobProperties().getCreationTimeInMs()) <= ifModifiedSinceMs) { responseChannel.setStatus(ResponseStatus.NotModified); } else { if (options.getRange() != null) { responseChannel.setStatus(ResponseStatus.PartialContent); } setGetBlobResponseHeaders(blobInfo, options, responseChannel); setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel); responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion()); } setCacheHeaders(restRequest, responseChannel); } else { if (subResource.equals(RestUtils.SubResource.BlobInfo)) { setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); responseChannel.setHeader(RestUtils.Headers.LIFE_VERSION, blobInfo.getLifeVersion()); } else if (subResource.equals(SubResource.Segment)) { setGetBlobResponseHeaders(blobInfo, options, responseChannel); setBlobPropertiesHeaders(blobInfo.getBlobProperties(), responseChannel); setAccountAndContainerHeaders(restRequest, responseChannel); } if (!setUserMetadataHeaders(blobInfo.getUserMetadata(), responseChannel)) { restRequest.setArg(InternalKeys.SEND_USER_METADATA_AS_RESPONSE_BODY, true); } } } break; case POST: responseChannel.setStatus(ResponseStatus.Created); responseChannel.setHeader(RestUtils.Headers.CONTENT_LENGTH, 0); responseChannel.setHeader(RestUtils.Headers.CREATION_TIME, new Date(blobInfo.getBlobProperties().getCreationTimeInMs())); break; case OPTIONS: case PUT: break; default: exception = new RestServiceException("Cannot process response for request with method " + restMethod, RestServiceErrorCode.InternalServerError); } } catch (RestServiceException e) { exception = e; } } frontendMetrics.securityServiceProcessResponseTimeInMs.update(System.currentTimeMillis() - startTimeMs); callback.onCompletion(null, exception); } AmbrySecurityService(FrontendConfig frontendConfig, FrontendMetrics frontendMetrics,
      UrlSigningService urlSigningService, QuotaManager quotaManager); @Override void preProcessRequest(RestRequest restRequest, Callback<Void> callback); @Override void processRequest(RestRequest restRequest, Callback<Void> callback); @Override void postProcessRequest(RestRequest restRequest, Callback<Void> callback); @Override void processResponse(RestRequest restRequest, RestResponseChannel responseChannel, BlobInfo blobInfo,
      Callback<Void> callback); @Override void close();  }