From 14c6f67ebf5b5777700cb11d693bb6b4b65383b2 Mon Sep 17 00:00:00 2001
From: Thomas Florio <thomas.florio@suse.com>
Date: Tue, 4 Feb 2025 11:34:31 +0100
Subject: [PATCH] Improve logging during authorization refresh

---
 buildconf/LICENSE.txt                                                               |    2 
 code/src/com/redhat/rhn/domain/scc/SCCRepository.java                               |   14 +--
 code/src/com/redhat/rhn/domain/scc/SCCRepositoryAuth.java                           |    7 -
 code/src/com/redhat/rhn/frontend/xmlrpc/sync/content/LocalDirContentSyncSource.java |   14 ++-
 code/src/com/redhat/rhn/frontend/xmlrpc/sync/content/RMTContentSyncSource.java      |   14 ++-
 code/src/com/redhat/rhn/frontend/xmlrpc/sync/content/SCCContentSyncSource.java      |   14 ++-
 code/src/com/redhat/rhn/manager/content/ContentSyncManager.java                     |   44 ++++++++--
 7 files changed, 72 insertions(+), 37 deletions(-)

--- a/buildconf/LICENSE.txt
+++ b/buildconf/LICENSE.txt
@@ -1,5 +1,5 @@
 ^/\*$
-^ \* Copyright \(c\) (20([0123]\d|20)--)?20(1\d|2[01234]) (Red Hat, Inc.|SUSE LLC)$
+^ \* Copyright \(c\) (20([0123]\d|20)--)?20(1\d|2[012345]) (Red Hat, Inc.|SUSE LLC)$)+
 ^ \*$
 ^ \* This software is licensed to you under the GNU General Public License,$
 ^ \* version 2 \(GPLv2\). There is NO WARRANTY for this software, express or$
--- a/code/src/com/redhat/rhn/domain/scc/SCCRepository.java
+++ b/code/src/com/redhat/rhn/domain/scc/SCCRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014--2018 SUSE LLC
+ * Copyright (c) 2014--2025 SUSE LLC
  *
  * This software is licensed to you under the GNU General Public License,
  * version 2 (GPLv2). There is NO WARRANTY for this software, express or
@@ -7,10 +7,6 @@
  * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
  * along with this software; if not, see
  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
- *
- * Red Hat trademarks are not licensed under GPLv2. No permission is
- * granted to use or replicate Red Hat trademarks that are incorporated
- * in this software or its documentation.
  */
 package com.redhat.rhn.domain.scc;
 
@@ -339,8 +335,10 @@ public class SCCRepository extends BaseD
     @Override
     public String toString() {
         return new ToStringBuilder(this)
-        .append("sccId", getSccId())
-        .append("description", getDescription())
-        .toString();
+            .append("sccId", getSccId())
+            .append("name", getName())
+            .append("description", getDescription())
+            .append("url", getUrl())
+            .toString();
     }
 }
--- a/code/src/com/redhat/rhn/domain/scc/SCCRepositoryAuth.java
+++ b/code/src/com/redhat/rhn/domain/scc/SCCRepositoryAuth.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 SUSE LLC
+ * Copyright (c) 2018--2025 SUSE LLC
  *
  * This software is licensed to you under the GNU General Public License,
  * version 2 (GPLv2). There is NO WARRANTY for this software, express or
@@ -7,10 +7,6 @@
  * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
  * along with this software; if not, see
  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
- *
- * Red Hat trademarks are not licensed under GPLv2. No permission is
- * granted to use or replicate Red Hat trademarks that are incorporated
- * in this software or its documentation.
  */
 package com.redhat.rhn.domain.scc;
 
@@ -231,6 +227,7 @@ public abstract class SCCRepositoryAuth
         return new ToStringBuilder(this)
                 .append("id", getId())
                 .append("repo", Objects.toString(getRepo()))
+                .append("credentials", credentials)
                 .toString();
     }
 }
--- a/code/src/com/redhat/rhn/frontend/xmlrpc/sync/content/LocalDirContentSyncSource.java
+++ b/code/src/com/redhat/rhn/frontend/xmlrpc/sync/content/LocalDirContentSyncSource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 SUSE LLC
+ * Copyright (c) 2023--2025 SUSE LLC
  *
  * This software is licensed to you under the GNU General Public License,
  * version 2 (GPLv2). There is NO WARRANTY for this software, express or
@@ -7,10 +7,6 @@
  * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
  * along with this software; if not, see
  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
- *
- * Red Hat trademarks are not licensed under GPLv2. No permission is
- * granted to use or replicate Red Hat trademarks that are incorporated
- * in this software or its documentation.
  */
 
 package com.redhat.rhn.frontend.xmlrpc.sync.content;
@@ -69,4 +65,12 @@ public class LocalDirContentSyncSource i
 
         return new SCCFileClient(new SCCConfig(localAbsolutePath));
     }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("LocalDirContentSyncSource{");
+        sb.append("path=").append(path);
+        sb.append('}');
+        return sb.toString();
+    }
 }
--- a/code/src/com/redhat/rhn/frontend/xmlrpc/sync/content/RMTContentSyncSource.java
+++ b/code/src/com/redhat/rhn/frontend/xmlrpc/sync/content/RMTContentSyncSource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 SUSE LLC
+ * Copyright (c) 2023--2025 SUSE LLC
  *
  * This software is licensed to you under the GNU General Public License,
  * version 2 (GPLv2). There is NO WARRANTY for this software, express or
@@ -7,10 +7,6 @@
  * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
  * along with this software; if not, see
  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
- *
- * Red Hat trademarks are not licensed under GPLv2. No permission is
- * granted to use or replicate Red Hat trademarks that are incorporated
- * in this software or its documentation.
  */
 
 package com.redhat.rhn.frontend.xmlrpc.sync.content;
@@ -78,4 +74,12 @@ public class RMTContentSyncSource implem
             throw new ContentSyncSourceException(e);
         }
     }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("RMTContentSyncSource{");
+        sb.append("credentials=").append(credentials);
+        sb.append('}');
+        return sb.toString();
+    }
 }
--- a/code/src/com/redhat/rhn/frontend/xmlrpc/sync/content/SCCContentSyncSource.java
+++ b/code/src/com/redhat/rhn/frontend/xmlrpc/sync/content/SCCContentSyncSource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 SUSE LLC
+ * Copyright (c) 2023--2025 SUSE LLC
  *
  * This software is licensed to you under the GNU General Public License,
  * version 2 (GPLv2). There is NO WARRANTY for this software, express or
@@ -7,10 +7,6 @@
  * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
  * along with this software; if not, see
  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
- *
- * Red Hat trademarks are not licensed under GPLv2. No permission is
- * granted to use or replicate Red Hat trademarks that are incorporated
- * in this software or its documentation.
  */
 
 package com.redhat.rhn.frontend.xmlrpc.sync.content;
@@ -72,4 +68,12 @@ public class SCCContentSyncSource implem
             throw new ContentSyncSourceException(e);
         }
     }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("SCCContentSyncSource{");
+        sb.append("credentials=").append(credentials);
+        sb.append('}');
+        return sb.toString();
+    }
 }
--- a/code/src/com/redhat/rhn/manager/content/ContentSyncManager.java
+++ b/code/src/com/redhat/rhn/manager/content/ContentSyncManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014--2021 SUSE LLC
+ * Copyright (c) 2014--2025 SUSE LLC
  *
  * This software is licensed to you under the GNU General Public License,
  * version 2 (GPLv2). There is NO WARRANTY for this software, express or
@@ -7,10 +7,6 @@
  * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
  * along with this software; if not, see
  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
- *
- * Red Hat trademarks are not licensed under GPLv2. No permission is
- * granted to use or replicate Red Hat trademarks that are incorporated
- * in this software or its documentation.
  */
 package com.redhat.rhn.manager.content;
 
@@ -569,15 +565,17 @@ public class ContentSyncManager {
             filterCredentials().stream()
                 .filter(source -> !excludeSCC || !(source instanceof SCCContentSyncSource))
                 .forEach(source -> {
-                    LOG.debug("Getting repos for: {}", source);
+                    LOG.info("Getting repos for: {}", source);
                     List<SCCRepositoryJson> repos = source.match(
                         scc -> {
                             try {
+                                LOG.info("Using SCC client to call listRepositories");
                                 SCCClient client = getSCCClient(source);
                                 return client.listRepositories();
                             }
                             catch (SCCClientException e) {
                                 // test for OES credentials
+                                LOG.info("Client exception detected, attempting OES credentials");
                                 SCCCredentials cred = scc.getCredentials(SCCCredentials.class)
                                     .orElseThrow(() -> new ContentSyncException("Invalid credentials type"));
 
@@ -585,6 +583,8 @@ public class ContentSyncManager {
                                     LOG.info("Credential is not an OES credentials");
                                     throw new ContentSyncException(e);
                                 }
+
+                                LOG.info("OES credentials OK.");
                                 return Collections.emptyList();
                             }
                         },
@@ -622,6 +622,7 @@ public class ContentSyncManager {
                         }
                     );
 
+                    LOG.info("Collected {} repositories. Refreshing authentications", repos.size());
                     LinkedList<SCCRepositoryJson> allReposList = new LinkedList<>(repos);
                     allReposList.addAll(getAdditionalRepositories());
                     refreshRepositoriesAuthentication(allReposList, source, mirrorUrl);
@@ -934,6 +935,8 @@ public class ContentSyncManager {
         List<SCCRepositoryJson> nonOESJRepos = repositories.stream()
             .filter(jsonRepo -> oesRepos.stream().noneMatch(oes -> oes.getSccId().equals(jsonRepo.getSCCId())))
             .collect(Collectors.toList());
+        LOG.info("Found {} OES repositories", oesRepos.size());
+        LOG.info("Found {} non-OES json repositories", nonOESJRepos.size());
 
         for (SCCRepositoryJson jsonRepo : nonOESJRepos) {
             SCCRepository repo = availableReposById.get(jsonRepo.getSCCId());
@@ -1006,6 +1009,7 @@ public class ContentSyncManager {
             });
 
         }
+        LOG.info("Repository SCC ids of the refreshed non-OES json repositories: {}", repoIdsFromCredential);
 
         // OES
         source.getCredentials(SCCCredentials.class)
@@ -1013,11 +1017,18 @@ public class ContentSyncManager {
 
         //DELETE OLD
         // check if we have to remove auths which exists before
+        LOG.info("Total number of repositories from this credentials: {}", repoIdsFromCredential.size());
         List<SCCRepositoryAuth> authList = SCCCachingFactory.lookupRepositoryAuthByCredential(source);
         authList.stream()
                 .filter(repoAuth -> repoAuth.cloudRmtAuth().isEmpty()) // rmtAuth is handled elsewhere (where?)
                 .filter(repoAuth -> !repoIdsFromCredential.contains(repoAuth.getRepo().getSccId()))
-                .forEach(SCCCachingFactory::deleteRepositoryAuth);
+                .forEach(repoAuth -> {
+                    LOG.info("Delete repository auth {}. RMT? {} Not contained? {}" , repoAuth,
+                        repoAuth.cloudRmtAuth().isEmpty(),
+                        !repoIdsFromCredential.contains(repoAuth.getRepo().getSccId())
+                    );
+                    SCCCachingFactory.deleteRepositoryAuth(repoAuth);
+                });
     }
 
     private void generatePtfChannels(List<SCCRepositoryJson> repositories) {
@@ -1155,10 +1166,13 @@ public class ContentSyncManager {
         List<Long> oesRepoIds = new LinkedList<>();
         //TODO: separate OES Credentials
         if (!(c == null || accessibleUrl(OES_URL, c.getUsername(), c.getPassword()))) {
+            LOG.info("credentials are not null and URL is not accessible, returning empty list");
             return oesRepoIds;
         }
+        LOG.info("Looping over {} OES repositories for credentials {}", oesRepos.size(), c);
         for (SCCRepository repo : oesRepos) {
             Set<SCCRepositoryAuth> allAuths = repo.getRepositoryAuth();
+            LOG.info("allAuths: {}", allAuths);
             Set<SCCRepositoryAuth> authsThisCred = allAuths.stream()
                     .filter(a -> {
                         if (c == null) {
@@ -1169,6 +1183,7 @@ public class ContentSyncManager {
                         }
                     })
                     .collect(Collectors.toSet());
+            LOG.info("authsThisCred: {}", authsThisCred);
             if (authsThisCred.size() > 1) {
                 LOG.error("More than 1 authentication found for one credential - removing all");
                 authsThisCred.forEach(a -> {
@@ -1180,23 +1195,29 @@ public class ContentSyncManager {
             }
             SCCRepositoryAuth newAuth = new SCCRepositoryBasicAuth();
             if (c == null) {
+                LOG.info("Credentials are null. We need to check every repo if it is available.");
                 // we need to check every repo if it is available
                 String url = MgrSyncUtils.urlToFSPath(repo.getUrl(), repo.getName()).toString();
                 try {
                     if (!accessibleUrl(buildRepoFileUrls(url, repo))) {
+                        LOG.info("Not accessible, skipping repo {}", repo);
                         continue;
                     }
                 }
                 catch (URISyntaxException e) {
-                    LOG.error("Failed to parse URL", e);
+                    LOG.error("Failed to parse URL, skipping repo {}", repo, e);
                     continue;
                 }
+
+                LOG.info("Check ok. Setting NoAuth for repo {}", repo);
                 newAuth = new SCCRepositoryNoAuth();
             }
             // this repo exists and is accessible
+            LOG.info("Repo {} exists and is accessible with auth {}, adding it", repo, newAuth.getClass().getName());
             oesRepoIds.add(repo.getSccId());
             if (authsThisCred.isEmpty()) {
                 // We need to create a new auth for this repo
+                LOG.info("No existing auth. Saving it");
                 newAuth.setCredentials(c);
                 newAuth.setRepo(repo);
                 allAuths.add(newAuth);
@@ -1210,10 +1231,17 @@ public class ContentSyncManager {
                 if (updateCS != null) {
                     updateCS.setMetadataSigned(repo.isSigned());
                     updateCS.setSourceUrl(contentSourceUrlOverwrite(repo, exAuth.getUrl(), mirrorUrl));
+                    LOG.info("Updating existing auth {} to isSigned: {}, sourceUrl: {}",
+                        exAuth, updateCS.getMetadataSigned(), updateCS.getSourceUrl());
                     ChannelFactory.save(updateCS);
                 }
+                else {
+                    LOG.info("No content source for {}. Skipping", exAuth);
+                }
             }
         }
+
+        LOG.info("Repository SCC ids of the refreshed OES repositories: {}", oesRepoIds);
         return oesRepoIds;
     }
 
