SLING-11150 - Return package id in the DistributionResponse to provide a deterministic way to track distribution status (#10)


Co-authored-by: amjain <amjain@adobe.com>
diff --git a/src/main/java/org/apache/sling/distribution/DistributionResponse.java b/src/main/java/org/apache/sling/distribution/DistributionResponse.java
index 55c936f..e52f390 100644
--- a/src/main/java/org/apache/sling/distribution/DistributionResponse.java
+++ b/src/main/java/org/apache/sling/distribution/DistributionResponse.java
@@ -28,7 +28,7 @@
  * {@link org.apache.sling.distribution.DistributionRequest} as handled by a certain distribution agent.
  * Such a response will include the {@link org.apache.sling.distribution.DistributionRequestState state} of
  * the {@link org.apache.sling.distribution.DistributionRequest request} and optionally a message for more
- * verbose information about the outcome of the request.
+ * verbose information about the outcome of the request and additional {@link DistributionResponseInfo properties}.
  */
 @ProviderType
 public interface DistributionResponse {
@@ -57,4 +57,12 @@
      */
     @Nullable
     String getMessage();
+
+    /**
+     * returns additional properties related to the {@link DistributionRequest}
+     * 
+     * @return additional properties
+     */
+    @Nonnull
+    DistributionResponseInfo getDistributionInfo();
 }
diff --git a/src/main/java/org/apache/sling/distribution/DistributionResponseInfo.java b/src/main/java/org/apache/sling/distribution/DistributionResponseInfo.java
new file mode 100644
index 0000000..e7b4215
--- /dev/null
+++ b/src/main/java/org/apache/sling/distribution/DistributionResponseInfo.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.distribution;
+
+import javax.annotation.Nonnull;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * A {@link DistributionResponseInfo} represents an additional info for the {@link DistributionRequest request} 
+ */
+@ProviderType
+public interface DistributionResponseInfo {
+    DistributionResponseInfo NONE = new DistributionResponseInfo() {
+        @Nonnull @Override public String getId() {
+            return "";
+        }
+    };
+    
+    /**
+     * returns the identifier of the associated {@link DistributionRequest}
+     *
+     * @return the id of the associated request
+     */
+    @Nonnull
+    String getId();
+}
diff --git a/src/main/java/org/apache/sling/distribution/package-info.java b/src/main/java/org/apache/sling/distribution/package-info.java
index ab781c9..d8b03c6 100644
--- a/src/main/java/org/apache/sling/distribution/package-info.java
+++ b/src/main/java/org/apache/sling/distribution/package-info.java
@@ -18,5 +18,5 @@
  */
 
 @javax.annotation.ParametersAreNonnullByDefault
-@org.osgi.annotation.versioning.Version("0.3.1")
+@org.osgi.annotation.versioning.Version("0.4.1")
 package org.apache.sling.distribution;
diff --git a/src/test/java/org/apache/sling/distribution/DistributionResponseTest.java b/src/test/java/org/apache/sling/distribution/DistributionResponseTest.java
new file mode 100644
index 0000000..fa1906d
--- /dev/null
+++ b/src/test/java/org/apache/sling/distribution/DistributionResponseTest.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.distribution;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Tests for {@link DistributionResponse}
+ */
+public class DistributionResponseTest {
+    @Test
+    public void emptyDistributionResponse() {
+        DistributionResponse res = new TestDistributionResponse(DistributionRequestState.DISTRIBUTED, "");
+        assertNotNull(res.getDistributionInfo());
+        assertEquals("", res.getDistributionInfo().getId());
+    }
+    
+    @Test
+    public void nullDistributionResponse() {
+        DistributionResponse res = new TestDistributionResponse(DistributionRequestState.DISTRIBUTED, "", null);
+        assertNull(res.getDistributionInfo());
+    }
+
+    @Test
+    public void nonEmptyDistributionResponse() {
+        DistributionResponse res1 = new TestDistributionResponse(DistributionRequestState.DISTRIBUTED, "success",
+            new DistributionResponseInfo() {
+                @Nonnull @Override public String getId() {
+                    return "res1";
+                }
+            });
+
+        assertNotNull(res1.getDistributionInfo());
+        assertEquals("res1", res1.getDistributionInfo().getId());
+    }
+    
+    class TestDistributionResponse implements DistributionResponse {
+        private final DistributionRequestState state;
+
+        private final String message;
+        private final DistributionResponseInfo info;
+        
+        TestDistributionResponse(DistributionRequestState state, String message) {
+            this(state, message, DistributionResponseInfo.NONE);
+        }
+
+        TestDistributionResponse(DistributionRequestState state, String message, DistributionResponseInfo info) {
+            this.state = state;
+            this.message = message;
+            this.info = info;
+        }
+
+        @Override public boolean isSuccessful() {
+            return false;
+        }
+
+        @Nonnull @Override public DistributionRequestState getState() {
+            return state;
+        }
+
+        @Nullable @Override public String getMessage() {
+            return message;
+        }
+
+        @Nonnull @Override public DistributionResponseInfo getDistributionInfo() {
+            return info;
+        }
+    }
+}