Add method that retrieve UUID for SCC that a specific SCS points to
Solves: Jira GER-1545
Change-Id: Idd246fd763e5aea9535a662ebe4be7e2b9ef57b8
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventHub.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventHub.java
index 8e58fbb..347f5fa 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventHub.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventHub.java
@@ -16,6 +16,7 @@
import com.googlesource.gerrit.plugins.eventseiffel.cache.EiffelEventIdLookupException;
import com.googlesource.gerrit.plugins.eventseiffel.eiffel.EventKey;
+import com.googlesource.gerrit.plugins.eventseiffel.eiffel.SourceChangeEventKey;
import com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelEvent;
import java.util.List;
import java.util.Optional;
@@ -105,6 +106,22 @@
* @throws EiffelEventIdLookupException when failing to lookup event from Eiffel.
*/
public Optional<List<UUID>> getParentLinks(EventKey key) throws EiffelEventIdLookupException;
+
+ /**
+ * If an event exists, already published or awaiting publish in this EiffelEventHub, such that:
+ *
+ * <p>{@code EventKey.fromEvent(this).equals(EventKey.fromEvent(existing) &&
+ * this.getEventType().equals(SCS)}
+ *
+ * <p>is true, the links.target for the link where links.type is CHANGE is returned, otherwise
+ * Optional.empty().
+ *
+ * @param key SourceChangeEventKey
+ * @return Optional<UUID> event.links.target
+ * @throws EiffelEventIdLookupException when failing to lookup event from Eiffel.
+ */
+ public Optional<UUID> getSccEventLink(SourceChangeEventKey key)
+ throws EiffelEventIdLookupException;
/** Start publishing events to Eiffel. */
public void startPublishing();
/** Stop publishing events to Eiffel. */
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventHubImpl.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventHubImpl.java
index 2138164..e73dbd2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventHubImpl.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/EiffelEventHubImpl.java
@@ -15,6 +15,7 @@
package com.googlesource.gerrit.plugins.eventseiffel;
import static com.google.common.base.Preconditions.checkState;
+import static com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelLinkType.CHANGE;
import static com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelLinkType.PREVIOUS_VERSION;
import com.google.common.collect.Lists;
@@ -198,6 +199,29 @@
}
@Override
+ public Optional<UUID> getSccEventLink(SourceChangeEventKey key)
+ throws EiffelEventIdLookupException {
+ final ReentrantLock idLookupLock = this.idLookupLock;
+ idLookupLock.lock();
+ try {
+ EiffelEvent fromHub = eventsInQueue.getOrDefault(key, null);
+ if (fromHub != null) {
+ if (key.matches(fromHub)) {
+ return Arrays.stream(fromHub.links)
+ .filter(link -> link.type == CHANGE)
+ .map(link -> link.target)
+ .findAny();
+ }
+ throw new EiffelEventIdLookupException(
+ "Key: %s does not match found event: %s.", key, EventKey.fromEvent(fromHub));
+ }
+ } finally {
+ idLookupLock.unlock();
+ }
+ return idCache.getSccEventLink(key);
+ }
+
+ @Override
public boolean isOpen() {
return open;
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/cache/EiffelEventIdCache.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/cache/EiffelEventIdCache.java
index 59775e0..c542821 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/cache/EiffelEventIdCache.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/cache/EiffelEventIdCache.java
@@ -15,6 +15,7 @@
package com.googlesource.gerrit.plugins.eventseiffel.cache;
import com.googlesource.gerrit.plugins.eventseiffel.eiffel.EventKey;
+import com.googlesource.gerrit.plugins.eventseiffel.eiffel.SourceChangeEventKey;
import com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelEvent;
import java.util.List;
import java.util.Optional;
@@ -49,6 +50,19 @@
Optional<List<UUID>> getParentLinks(EventKey key) throws EiffelEventIdLookupException;
/**
+ * Returns the id that is linked with CHANGE by SCS-event that matches:
+ *
+ * <p>{@code EventKey.fromEvent(event).equals(key)}
+ *
+ * <p>Optional.Empty if no such event exists or if key is not a SCS key
+ *
+ * @param key
+ * @return Optional<UUID>
+ * @throws EiffelEventIdLookupException if value failed to load.
+ */
+ Optional<UUID> getSccEventLink(SourceChangeEventKey key) throws EiffelEventIdLookupException;
+
+ /**
* Returns the id of an event that matches the repo and the commit:
*
* <p>Optional.Empty if no such event exists.
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/cache/EiffelEventIdCacheImpl.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/cache/EiffelEventIdCacheImpl.java
index 923039b..0b14355 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/cache/EiffelEventIdCacheImpl.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/cache/EiffelEventIdCacheImpl.java
@@ -143,6 +143,19 @@
}
}
+ @Override
+ public Optional<UUID> getSccEventLink(SourceChangeEventKey key)
+ throws EiffelEventIdLookupException {
+ try {
+ return eventStorage.getSccEventLink(key);
+ } catch (EventStorageException e) {
+ throw new EiffelEventIdLookupException(
+ e,
+ key.type(),
+ String.format("failed to lookup Eiffel SCC event link for %s from GraphQl", key));
+ }
+ }
+
/* (non-Javadoc)
* @see com.googlesource.gerrit.plugins.eventseiffel.EiffelEventIdCache#putId(com.googlesource.gerrit.plugins.eventseiffel.eiffel.EiffelEvent)
*/
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EiffelClient.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EiffelClient.java
index 002f6bc..1ae2d66 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EiffelClient.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EiffelClient.java
@@ -17,6 +17,7 @@
import com.google.common.flogger.FluentLogger;
import com.googlesource.gerrit.plugins.eventseiffel.config.EiffelRepoApiConfig;
import com.googlesource.gerrit.plugins.eventseiffel.eiffel.EventKey;
+import com.googlesource.gerrit.plugins.eventseiffel.eiffel.SourceChangeEventKey;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.http.HttpClient;
@@ -65,6 +66,11 @@
}
@Override
+ public Optional<UUID> getSccEventLink(SourceChangeEventKey key) throws EventStorageException {
+ return restClient.getSccEventLink(key);
+ }
+
+ @Override
public List<UUID> getScsIds(String repo, String commit) throws EventStorageException {
return graphQlClient.getScsIds(repo, commit);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EiffelGoRestClient.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EiffelGoRestClient.java
index 1936110..784c18a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EiffelGoRestClient.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EiffelGoRestClient.java
@@ -14,6 +14,7 @@
package com.googlesource.gerrit.plugins.eventseiffel.eiffel.api;
+import static com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelLinkType.CHANGE;
import static com.googlesource.gerrit.plugins.eventseiffel.eiffel.dto.EiffelLinkType.PREVIOUS_VERSION;
import com.github.rholder.retry.RetryException;
@@ -96,6 +97,33 @@
return Optional.of(qr.getParentLinks());
}
+ public Optional<UUID> getSccEventLink(SourceChangeEventKey key) throws EventStorageException {
+ String query;
+ switch (key.type()) {
+ case SCS:
+ SourceChangeEventKey scsKey = (SourceChangeEventKey) key;
+ query =
+ String.format(
+ LINKS_ID_URL,
+ scsKey.type().getType(),
+ scsKey.repo(),
+ scsKey.branch(),
+ scsKey.commit());
+ break;
+ default:
+ return Optional.empty();
+ }
+ QueryResult qr = restQuery(query);
+ if (qr == null || qr.isEmpty()) {
+ return Optional.empty();
+ }
+
+ if (qr.nbrOfFoundEvents() > 1) {
+ logger.atWarning().log("More than one event found (using first) for query:\"%s\"", query);
+ }
+ return qr.getSccLink();
+ }
+
private QueryResult restQuery(String query) throws EventStorageException {
HttpResponse<String> response;
try {
@@ -155,6 +183,10 @@
return getLinks(PREVIOUS_VERSION).collect(Collectors.toList());
}
+ Optional<UUID> getSccLink() {
+ return getLinks(CHANGE).findAny();
+ }
+
private Stream<UUID> getLinks(EiffelLinkType linkType) {
return Arrays.stream(items.get(0).links)
.filter(link -> link.type == linkType)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EventStorage.java b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EventStorage.java
index 56be459..ed2bb68 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EventStorage.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/eventseiffel/eiffel/api/EventStorage.java
@@ -17,6 +17,7 @@
import com.google.gerrit.extensions.restapi.NotImplementedException;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.eventseiffel.eiffel.EventKey;
+import com.googlesource.gerrit.plugins.eventseiffel.eiffel.SourceChangeEventKey;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@@ -44,6 +45,16 @@
public Optional<List<UUID>> getParentLinks(EventKey key) throws EventStorageException;
/**
+ * Returns the links.target for links where links.type is CHANGE for the event that matches
+ * EventKey key. Optional.empty() if there exists no such event or if key is not of the type SCS.
+ *
+ * @param key
+ * @return {@link Optional} of {@link UUID} id of the linked event.
+ * @throws EventStorageException
+ */
+ public Optional<UUID> getSccEventLink(SourceChangeEventKey key) throws EventStorageException;
+
+ /**
* Returns the meta.ids of the SCS events that match the repo and the commitid.
*
* @param repo the repo of the SCS events.
@@ -67,6 +78,11 @@
}
@Override
+ public Optional<UUID> getSccEventLink(SourceChangeEventKey key) throws EventStorageException {
+ throw new NotImplementedException();
+ }
+
+ @Override
public List<UUID> getScsIds(String repo, String commit) throws EventStorageException {
throw new NotImplementedException();
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/TestEventHub.java b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/TestEventHub.java
index 9957d69..f2654d3 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/TestEventHub.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/TestEventHub.java
@@ -83,6 +83,19 @@
.collect(Collectors.toList()));
}
+ @Override
+ public Optional<UUID> getSccEventLink(SourceChangeEventKey key)
+ throws EiffelEventIdLookupException {
+ return findEvent(key)
+ .map(
+ event ->
+ Arrays.stream(event.links)
+ .filter(link -> link.type.equals(EiffelLinkType.CHANGE))
+ .map(link -> link.target)
+ .findAny()
+ .get());
+ }
+
private Optional<EiffelEvent> findEvent(EventKey key) {
for (EiffelEvent event : EVENTS) {
if (key.equals(EventKey.fromEvent(event))) {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/TestEventStorage.java b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/TestEventStorage.java
index 74196c8..7f70500 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/TestEventStorage.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/eventseiffel/TestEventStorage.java
@@ -70,6 +70,11 @@
return Optional.of(Lists.newArrayList());
}
+ @Override
+ public Optional<UUID> getSccEventLink(SourceChangeEventKey key) throws EventStorageException {
+ return Optional.empty();
+ }
+
private boolean equalsSCSWithRepoAndCommit(EventKey key, String repo, String commit) {
if (!key.type().equals(SCS)) return false;
SourceChangeEventKey scsKey = (SourceChangeEventKey) key;