@@ -80,6 +80,7 @@ public StorageObject apply(BlobInfo blobInfo) {
8080 private final String contentLanguage ;
8181 private final Integer componentCount ;
8282 private final boolean isDirectory ;
83+ private final CustomerEncryption customerEncryption ;
8384
8485 /**
8586 * This class is meant for internal use only. Users are discouraged from using this class.
@@ -92,6 +93,69 @@ public Set<Entry<K, V>> entrySet() {
9293 }
9394 }
9495
96+ /**
97+ * Objects of this class hold information on the customer-supplied encryption key, if the blob is
98+ * encrypted using such a key.
99+ */
100+ public static class CustomerEncryption implements Serializable {
101+
102+ private static final long serialVersionUID = -2133042982786959351L ;
103+
104+ private final String encryptionAlgorithm ;
105+ private final String keySha256 ;
106+
107+ CustomerEncryption (String encryptionAlgorithm , String keySha256 ) {
108+ this .encryptionAlgorithm = encryptionAlgorithm ;
109+ this .keySha256 = keySha256 ;
110+ }
111+
112+ /**
113+ * Returns the algorithm used to encrypt the blob.
114+ */
115+ public String encryptionAlgorithm () {
116+ return encryptionAlgorithm ;
117+ }
118+
119+ /**
120+ * Returns the SHA256 hash of the encryption key.
121+ */
122+ public String keySha256 () {
123+ return keySha256 ;
124+ }
125+
126+ @ Override
127+ public String toString () {
128+ return MoreObjects .toStringHelper (this )
129+ .add ("encryptionAlgorithm" , encryptionAlgorithm ())
130+ .add ("keySha256" , keySha256 ())
131+ .toString ();
132+ }
133+
134+ @ Override
135+ public final int hashCode () {
136+ return Objects .hash (encryptionAlgorithm , keySha256 );
137+ }
138+
139+ @ Override
140+ public final boolean equals (Object obj ) {
141+ return obj == this
142+ || obj != null
143+ && obj .getClass ().equals (CustomerEncryption .class )
144+ && Objects .equals (toPb (), ((CustomerEncryption ) obj ).toPb ());
145+ }
146+
147+ StorageObject .CustomerEncryption toPb () {
148+ return new StorageObject .CustomerEncryption ()
149+ .setEncryptionAlgorithm (encryptionAlgorithm )
150+ .setKeySha256 (keySha256 );
151+ }
152+
153+ static CustomerEncryption fromPb (StorageObject .CustomerEncryption customerEncryptionPb ) {
154+ return new CustomerEncryption (customerEncryptionPb .getEncryptionAlgorithm (),
155+ customerEncryptionPb .getKeySha256 ());
156+ }
157+ }
158+
95159 /**
96160 * Builder for {@code BlobInfo}.
97161 */
@@ -193,6 +257,8 @@ public abstract static class Builder {
193257
194258 abstract Builder isDirectory (boolean isDirectory );
195259
260+ abstract Builder customerEncryption (CustomerEncryption customerEncryption );
261+
196262 /**
197263 * Creates a {@code BlobInfo} object.
198264 */
@@ -223,6 +289,7 @@ static final class BuilderImpl extends Builder {
223289 private Long updateTime ;
224290 private Long createTime ;
225291 private Boolean isDirectory ;
292+ private CustomerEncryption customerEncryption ;
226293
227294 BuilderImpl (BlobId blobId ) {
228295 this .blobId = blobId ;
@@ -237,6 +304,7 @@ static final class BuilderImpl extends Builder {
237304 contentDisposition = blobInfo .contentDisposition ;
238305 contentLanguage = blobInfo .contentLanguage ;
239306 componentCount = blobInfo .componentCount ;
307+ customerEncryption = blobInfo .customerEncryption ;
240308 acl = blobInfo .acl ;
241309 owner = blobInfo .owner ;
242310 size = blobInfo .size ;
@@ -386,6 +454,12 @@ Builder isDirectory(boolean isDirectory) {
386454 return this ;
387455 }
388456
457+ @ Override
458+ Builder customerEncryption (CustomerEncryption customerEncryption ) {
459+ this .customerEncryption = customerEncryption ;
460+ return this ;
461+ }
462+
389463 @ Override
390464 public BlobInfo build () {
391465 checkNotNull (blobId );
@@ -402,6 +476,7 @@ public BlobInfo build() {
402476 contentDisposition = builder .contentDisposition ;
403477 contentLanguage = builder .contentLanguage ;
404478 componentCount = builder .componentCount ;
479+ customerEncryption = builder .customerEncryption ;
405480 acl = builder .acl ;
406481 owner = builder .owner ;
407482 size = builder .size ;
@@ -631,6 +706,14 @@ public boolean isDirectory() {
631706 return isDirectory ;
632707 }
633708
709+ /**
710+ * Returns information on the customer-supplied encryption key, if the blob is encrypted using
711+ * such a key.
712+ */
713+ public CustomerEncryption customerEncryption () {
714+ return customerEncryption ;
715+ }
716+
634717 /**
635718 * Returns a builder for the current blob.
636719 */
@@ -696,6 +779,9 @@ public ObjectAccessControl apply(Acl acl) {
696779 firstNonNull (entry .getValue (), Data .<String >nullOf (String .class )));
697780 }
698781 }
782+ if (customerEncryption != null ) {
783+ storageObject .setCustomerEncryption (customerEncryption .toPb ());
784+ }
699785 storageObject .setMetadata (pbMetadata );
700786 storageObject .setCacheControl (cacheControl );
701787 storageObject .setContentEncoding (contentEncoding );
@@ -815,6 +901,9 @@ public Acl apply(ObjectAccessControl objectAccessControl) {
815901 if (storageObject .containsKey ("isDirectory" )) {
816902 builder .isDirectory (Boolean .TRUE );
817903 }
904+ if (storageObject .getCustomerEncryption () != null ) {
905+ builder .customerEncryption (CustomerEncryption .fromPb (storageObject .getCustomerEncryption ()));
906+ }
818907 return builder .build ();
819908 }
820909}
0 commit comments