public async create()

in src/blob/handlers/PageBlobHandler.ts [51:165]


  public async create(
    contentLength: number,
    blobContentLength: number,
    options: Models.PageBlobCreateOptionalParams,
    context: Context
  ): Promise<Models.PageBlobCreateResponse> {
    const blobCtx = new BlobStorageContext(context);
    const accountName = blobCtx.account!;
    const containerName = blobCtx.container!;
    const blobName = blobCtx.blob!;
    const date = blobCtx.startTime!;

    if (options.tier !== undefined) {
      throw StorageErrorFactory.getAccessTierNotSupportedForBlobType(
        context.contextId!
      );
    }

    if (contentLength !== 0) {
      throw StorageErrorFactory.getInvalidOperation(
        blobCtx.contextId!,
        "Content-Length must be 0 for Create Page Blob request."
      );
    }

    if (blobContentLength % 512 !== 0) {
      throw StorageErrorFactory.getInvalidOperation(
        blobCtx.contextId!,
        "x-ms-content-length must be aligned to a 512-byte boundary."
      );
    }

    options.blobHTTPHeaders = options.blobHTTPHeaders || {};
    const contentType =
      options.blobHTTPHeaders.blobContentType ||
      context.request!.getHeader("content-type") ||
      "application/octet-stream";

    // const accessTierInferred = options.pageBlobAccessTier === undefined;

    // Check Blob size match tier
    // if (
    //   !accessTierInferred &&
    //   blobContentLength > PageBlobAccessTierThreshold.get(tier)!
    // ) {
    //   throw StorageErrorFactory.getBlobBlobTierInadequateForContentLength(
    //     blobCtx.contextID!
    //   );
    // }

    // Preserve metadata key case
    const metadata = convertRawHeadersToMetadata(
      blobCtx.request!.getRawHeaders(), context.contextId!
    );

    const etag = newEtag();
    const blob: BlobModel = {
      deleted: false,
      metadata,
      accountName,
      containerName,
      name: blobName,
      properties: {
        creationTime: date,
        lastModified: date,
        etag,
        contentLength: blobContentLength,
        contentType,
        contentEncoding: options.blobHTTPHeaders.blobContentEncoding,
        contentLanguage: options.blobHTTPHeaders.blobContentLanguage,
        contentMD5: options.blobHTTPHeaders.blobContentMD5,
        contentDisposition: options.blobHTTPHeaders.blobContentDisposition,
        cacheControl: options.blobHTTPHeaders.blobCacheControl,
        blobSequenceNumber: options.blobSequenceNumber
          ? options.blobSequenceNumber
          : 0,
        blobType: Models.BlobType.PageBlob,
        leaseStatus: Models.LeaseStatusType.Unlocked,
        leaseState: Models.LeaseStateType.Available,
        serverEncrypted: true
        // TODO: May support setting this part for a premium storage account.
        // accessTier: accessTierInferred
        //   ? ((options.pageBlobAccessTier as any) as Models.AccessTier)
        //   : Models.AccessTier.P4, // TODO: Infer tier from size
        // accessTierInferred
      },
      snapshot: "",
      isCommitted: true,
      pageRangesInOrder: [],      
      blobTags: options.blobTagsString === undefined ? undefined : getTagsFromString(options.blobTagsString, context.contextId!),
    };

    // TODO: What's happens when create page blob right before commit block list? Or should we lock
    // Should we check if there is an uncommitted blob?
    await this.metadataStore.createBlob(
      context,
      blob,
      options.leaseAccessConditions,
      options.modifiedAccessConditions
    );

    const response: Models.PageBlobCreateResponse = {
      statusCode: 201,
      eTag: etag,
      lastModified: blob.properties.lastModified,
      contentMD5: blob.properties.contentMD5,
      requestId: context.contextId,
      version: BLOB_API_VERSION,
      date,
      isServerEncrypted: true,
      clientRequestId: options.requestId
    };

    return response;
  }