Repository: googleapis/java-storage
Pull request #1160 (2021-12-01 22:00:50)

fix: Remove all client side validation for OLM, allow nonspecific lif…
Removes client side validation by refactoring `LifecycleAction` into a non-abstract class and allowing for nonspecific lifecycle actions. 

frankyn: @JesseLovelace are you still addressing the clirr issue?

Patch:
diff --git a/README.md b/README.md
index d05eed11..42a0678c 100644
--- a/README.md
+++ b/README.md
@@ -56,13 +56,13 @@ implementation 'com.google.cloud:google-cloud-storage'
 If you are using Gradle without BOM, add this to your dependencies
 
 ```Groovy
-implementation 'com.google.cloud:google-cloud-storage:2.2.2'
+implementation 'com.google.cloud:google-cloud-storage:2.2.3'
 ```
 
 If you are using SBT, add this to your dependencies
 
 ```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-storage" % "2.2.2"
+libraryDependencies += "com.google.cloud" % "google-cloud-storage" % "2.2.3"
 ```
 
 ## Authentication
diff --git a/google-cloud-storage/clirr-ignored-differences.xml b/google-cloud-storage/clirr-ignored-differences.xml
new file mode 100644
index 00000000..18931676
--- /dev/null
+++ b/google-cloud-storage/clirr-ignored-differences.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- see https://www.mojohaus.org/clirr-maven-plugin/examples/ignored-differences.html -->
+<differences>
+    <difference>
+        <className>com/google/cloud/storage/BucketInfo$LifecycleRule$LifecycleAction</className>
+        <method>BucketInfo$LifecycleRule$LifecycleAction()</method>
+        <differenceType>7004</differenceType>
+    </difference>
+</differences>
diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java
index 83a836f7..2404a7c1 100644
--- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java
+++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java
@@ -548,8 +548,13 @@ public class BucketInfo implements Serializable {
                   StorageClass.valueOf(action.getStorageClass()));
           break;
         default:
-          throw new UnsupportedOperationException(
-              "The specified lifecycle action " + action.getType() + " is not currently supported");
+          log.warning(
+              "The lifecycle action "
+                  + action.getType()
+                  + " is not supported by this version of the library. "
+                  + "Attempting to update with this rule may cause errors. Please "
+                  + "update to the latest version of google-cloud-storage.");
+          lifecycleAction = LifecycleAction.newLifecycleAction("Unknown action");
       }
 
       Rule.Condition condition = rule.getCondition();
@@ -799,13 +804,21 @@ public class BucketInfo implements Serializable {
     }
 
     /**
-     * Base class for the Action to take when a Lifecycle Condition is met. Specific Actions are
+     * Base class for the Action to take when a Lifecycle Condition is met. Supported Actions are
      * expressed as subclasses of this class, accessed by static factory methods.
      */
-    public abstract static class LifecycleAction implements Serializable {
+    public static class LifecycleAction implements Serializable {
       private static final long serialVersionUID = 5801228724709173284L;
 
-      public abstract String getActionType();
+      private final String actionType;
+
+      public LifecycleAction(String actionType) {
+        this.actionType = actionType;
+      }
+
+      public String getActionType() {
+        return actionType;
+      }
 
       @Override
       public String toString() {
@@ -830,17 +843,24 @@ public class BucketInfo implements Serializable {
           StorageClass storageClass) {
         return new SetStorageClassLifecycleAction(storageClass);
       }
+
+      /**
+       * Creates a new {@code LifecycleAction , with no specific supported action associated with it. This
+       * is only intended as a "backup" for when the library doesn't recognize the type, and should
+       * generally not be used, instead use the supported actions, and upgrade the library if necessary
+       * to get new supported actions.
+       */
+      public static LifecycleAction newLifecycleAction(String actionType) {
+        return new LifecycleAction(actionType);
+      }
     }
 
     public static class DeleteLifecycleAction extends LifecycleAction {
       public static final String TYPE = "Delete";
       private static final long serialVersionUID = -2050986302222644873L;
 
-      private DeleteLifecycleAction() {}
-
-      @Override
-      public String getActionType() {
-        return TYPE;
+      private DeleteLifecycleAction() {
+        super(TYPE);
       }
     }
 
@@ -851,14 +871,10 @@ public class BucketInfo implements Serializable {
       private final StorageClass storageClass;
 
       private SetStorageClassLifecycleAction(StorageClass storageClass) {
+        super(TYPE);
         this.storageClass = storageClass;
       }
 
-      @Override
-      public String getActionType() {
-        return TYPE;
-      }
-
       @Override
       public String toString() {
         return MoreObjects.toStringHelper(this)
@@ -1007,7 +1023,11 @@ public class BucketInfo implements Serializable {
 
     @Override
     void populateCondition(Rule.Condition condition) {
-      throw new UnsupportedOperationException();
+      log.warning(
+          "The lifecycle condition "
+              + condition
+              + " is not currently supported. Please update to the latest version of google-cloud-java."
+              + " Also, use LifecycleRule rather than the deprecated DeleteRule.");
     }
 
     private void writeObject(ObjectOutputStream out) throws IOException {
diff --git a/samples/snippets/src/main/java/com/example/storage/ConfigureRetries.java b/samples/snippets/src/main/java/com/example/storage/ConfigureRetries.java
index 9d037a82..e1db27ab 100644
--- a/samples/snippets/src/main/java/com/example/storage/ConfigureRetries.java
+++ b/samples/snippets/src/main/java/com/example/storage/ConfigureRetries.java
@@ -15,6 +15,7 @@
  */
 
 package com.example.storage;
+
 // [START storage_configure_retries]
 
 import com.google.api.gax.retrying.RetrySettings;


Test patch:
diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java
index c74625a1..2041de55 100644
--- a/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java
+++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java
@@ -314,6 +314,10 @@ public class BucketInfoTest {
     for (DeleteRule delRule : rules) {
       assertEquals(delRule, DeleteRule.fromPb(delRule.toPb()));
     }
+    Rule unsupportedRule =
+        new Rule().setAction(new Rule.Action().setType("This action doesn't exist"));
+    DeleteRule.fromPb(
+        unsupportedRule); // if this doesn't throw an exception, unsupported rules work
   }
 
   @Test
@@ -363,6 +367,17 @@ public class BucketInfoTest {
     assertEquals(StorageClass.COLDLINE.toString(), lifecycleRule.getAction().getStorageClass());
     assertEquals(30, lifecycleRule.getCondition().getDaysSinceCustomTime().intValue());
     assertNotNull(lifecycleRule.getCondition().getCustomTimeBefore());
+
+    Rule unsupportedRule =
+        new LifecycleRule(
+                LifecycleAction.newLifecycleAction("This action type doesn't exist"),
+                LifecycleCondition.newBuilder().setAge(10).build())
+            .toPb();
+    unsupportedRule.setAction(
+        unsupportedRule.getAction().setType("This action type also doesn't exist"));
+
+    LifecycleRule.fromPb(
+        unsupportedRule); // If this doesn't throw an exception, unsupported rules are working
   }
 
   @Test