Skip to content
Snippets Groups Projects
Commit eb00ba76 authored by Zachary Sabourin's avatar Zachary Sabourin
Browse files

Merge branch 'zacharysabourin/main/61' into 'main'

fix: Fix issue handling null values when augmenting profile, integrate Common ProjectService

Closes #61

See merge request !24
parents 7fcb2a65 5a15cd80
No related branches found
No related tags found
1 merge request!24fix: Fix issue handling null values when augmenting profile, integrate Common ProjectService
Pipeline #18819 failed
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<surefire-plugin.version>3.0.0-M5</surefire-plugin.version> <surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
<auto-value.version>1.8.2</auto-value.version> <auto-value.version>1.8.2</auto-value.version>
<hibernate.version>5.5.6.Final</hibernate.version> <hibernate.version>5.5.6.Final</hibernate.version>
<eclipse-api-version>0.7.4</eclipse-api-version> <eclipse-api-version>0.7.6-SNAPSHOT</eclipse-api-version>
<org.mapstruct.version>1.4.1.Final</org.mapstruct.version> <org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
<fdndb-api-version>1.0.4</fdndb-api-version> <fdndb-api-version>1.0.4</fdndb-api-version>
<sonar.sources>src/main</sonar.sources> <sonar.sources>src/main</sonar.sources>
......
/*********************************************************************
* Copyright (c) 2023 Eclipse Foundation.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Author: Zachary Sabourin <zachary.sabourin@eclipse-foundation.org>
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipsefoundation.profile.api;
import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipsefoundation.core.service.APIMiddleware.BaseAPIParameters;
/**
* Projects-API binding.
*/
@Path("/api")
@ApplicationScoped
@RegisterRestClient(configKey = "projects-api")
public interface ProjectAPI {
/**
* Fetches all spec projects from the projects-api.
*
* @param params The BaseAPIParameters
* @param isSpecProject Flag for matching against spec projects
* @return A Response containing the spec project entities if they exist.
*/
@GET
@Path("/projects")
Response getProjects(@BeanParam BaseAPIParameters params, @QueryParam("spec_project") int isSpecProject);
}
...@@ -81,18 +81,18 @@ public class DefaultProfileService implements ProfileService { ...@@ -81,18 +81,18 @@ public class DefaultProfileService implements ProfileService {
// Search for user in fdndb // Search for user in fdndb
Optional<PeopleData> fdnResult = getPerson(username); Optional<PeopleData> fdnResult = getPerson(username);
if (fdnResult.isPresent()) { if (fdnResult.isPresent()) {
return Optional.of(augmentSlimUser(buildSlimEfUser(fdnResult.get()))); return augmentSlimUser(buildSlimEfUser(fdnResult.get()));
} }
// If not found, search LDAP // If not found, search LDAP
Optional<LdapResult> result = ldapService.searchLdapByUsername(username); Optional<LdapResult> result = ldapService.searchLdapByUsername(username);
return result.isEmpty() ? Optional.empty() : Optional.of(augmentSlimUser(buildSlimEfUser(result.get()))); return result.isEmpty() ? Optional.empty() : augmentSlimUser(buildSlimEfUser(result.get()));
} }
@Override @Override
public Optional<EfUser> getFullProfileByHandle(String handle) { public Optional<EfUser> getFullProfileByHandle(String handle) {
Optional<LdapResult> result = ldapService.searchLdapByGhHandle(handle); Optional<LdapResult> result = ldapService.searchLdapByGhHandle(handle);
return result.isEmpty() ? Optional.empty() : Optional.of(augmentSlimUser(buildSlimEfUser(result.get()))); return result.isEmpty() ? Optional.empty() : augmentSlimUser(buildSlimEfUser(result.get()));
} }
@Override @Override
...@@ -100,12 +100,12 @@ public class DefaultProfileService implements ProfileService { ...@@ -100,12 +100,12 @@ public class DefaultProfileService implements ProfileService {
// Search for user in fdndb // Search for user in fdndb
Optional<PeopleData> fdnResult = getPersonByEmail(email); Optional<PeopleData> fdnResult = getPersonByEmail(email);
if (fdnResult.isPresent()) { if (fdnResult.isPresent()) {
return Optional.of(augmentSlimUser(buildSlimEfUser(fdnResult.get()))); return augmentSlimUser(buildSlimEfUser(fdnResult.get()));
} }
// If not found, search LDAP // If not found, search LDAP
Optional<LdapResult> result = ldapService.searchLdapByEmail(email); Optional<LdapResult> result = ldapService.searchLdapByEmail(email);
return result.isEmpty() ? Optional.empty() : Optional.of(augmentSlimUser(buildSlimEfUser(result.get()))); return result.isEmpty() ? Optional.empty() : augmentSlimUser(buildSlimEfUser(result.get()));
} }
@Override @Override
...@@ -217,23 +217,22 @@ public class DefaultProfileService implements ProfileService { ...@@ -217,23 +217,22 @@ public class DefaultProfileService implements ProfileService {
* @param slimUser The slimmed down EfUser. * @param slimUser The slimmed down EfUser.
* @return A populated EfUser entity with all relevant data. * @return A populated EfUser entity with all relevant data.
*/ */
private EfUser augmentSlimUser(Optional<EfUser> slimUser) { private Optional<EfUser> augmentSlimUser(Optional<EfUser> slimUser) {
if (slimUser.isEmpty()) { if (slimUser.isEmpty()) {
return null; return slimUser;
} }
EfUser slim = slimUser.get(); EfUser slim = slimUser.get();
LOGGER.debug("Building full EFUser: {}", slimUser.get().getName()); LOGGER.debug("Building full EFUser: {}", slimUser.get().getName());
return slim == null ? slim return Optional.of(slim.toBuilder()
: slimUser.get().toBuilder() .setEcaUrl(buildRelationshipUrl(slim.getName(), "eca"))
.setEcaUrl(buildRelationshipUrl(slim.getName(), "eca")) .setProjectsUrl(buildRelationshipUrl(slim.getName(), "projects"))
.setProjectsUrl(buildRelationshipUrl(slim.getName(), "projects")) .setGerritUrl(buildRelationshipUrl(slim.getName(), "gerrit"))
.setGerritUrl(buildRelationshipUrl(slim.getName(), "gerrit")) .setMailinglistUrl(buildRelationshipUrl(slim.getName(), "mailing-list"))
.setMailinglistUrl(buildRelationshipUrl(slim.getName(), "mailing-list")) .setMpcFavoritesUrl(urlConfig.marketplaceFavoritesUrl() + slim.getName())
.setMpcFavoritesUrl(urlConfig.marketplaceFavoritesUrl() + slim.getName()) .setEca(metadataService.getEcaStatus(slim.getName()))
.setEca(metadataService.getEcaStatus(slim.getName())) .setIsCommitter(getCommitterStatus(slim.getName()))
.setIsCommitter(getCommitterStatus(slim.getName())) .build());
.build();
} }
/** /**
...@@ -249,7 +248,7 @@ public class DefaultProfileService implements ProfileService { ...@@ -249,7 +248,7 @@ public class DefaultProfileService implements ProfileService {
Optional<PeopleData> result = cache.get(username, new MultivaluedMapImpl<>(), PeopleData.class, Optional<PeopleData> result = cache.get(username, new MultivaluedMapImpl<>(), PeopleData.class,
() -> peopleAPI.getPerson(username)); () -> peopleAPI.getPerson(username));
if (result.isEmpty()) { if (result.isEmpty()) {
LOGGER.error("Error fetching data for user: {}", username); LOGGER.error("Error - fdndb-api: No People results for user: {}", username);
return Optional.empty(); return Optional.empty();
} }
...@@ -269,7 +268,7 @@ public class DefaultProfileService implements ProfileService { ...@@ -269,7 +268,7 @@ public class DefaultProfileService implements ProfileService {
Optional<List<PeopleData>> result = cache.get(email, new MultivaluedMapImpl<>(), PeopleData.class, Optional<List<PeopleData>> result = cache.get(email, new MultivaluedMapImpl<>(), PeopleData.class,
() -> peopleAPI.getPeople(email)); () -> peopleAPI.getPeople(email));
if (result.isEmpty() || result.get().isEmpty()) { if (result.isEmpty() || result.get().isEmpty()) {
LOGGER.error("Error fetching data for user with email: {}", email); LOGGER.error("Error - fdndb-api: No People results for user with email: {}", email);
return Optional.empty(); return Optional.empty();
} }
...@@ -290,7 +289,7 @@ public class DefaultProfileService implements ProfileService { ...@@ -290,7 +289,7 @@ public class DefaultProfileService implements ProfileService {
Optional<AccountsProfileData> result = cache.get(username, new MultivaluedMapImpl<>(), Optional<AccountsProfileData> result = cache.get(username, new MultivaluedMapImpl<>(),
AccountsProfileData.class, () -> profileAPI.getDrupalProfileData(username)); AccountsProfileData.class, () -> profileAPI.getDrupalProfileData(username));
if (result.isEmpty()) { if (result.isEmpty()) {
LOGGER.error("Error fetching profile data for user: {}", username); LOGGER.error("Error - Drupal-API: No profile results for user: {}", username);
return Optional.empty(); return Optional.empty();
} }
...@@ -323,7 +322,7 @@ public class DefaultProfileService implements ProfileService { ...@@ -323,7 +322,7 @@ public class DefaultProfileService implements ProfileService {
Optional<List<FullPeopleProjectData>> results = cache.get(username, new MultivaluedMapImpl<>(), Optional<List<FullPeopleProjectData>> results = cache.get(username, new MultivaluedMapImpl<>(),
FullPeopleProjectData.class, () -> peopleAPI.getFullPeopleProjects(username)); FullPeopleProjectData.class, () -> peopleAPI.getFullPeopleProjects(username));
if (results.isEmpty()) { if (results.isEmpty()) {
LOGGER.warn("No projects associated with user: {}", username); LOGGER.warn("Error - fdndb-api: No project results for user: {}", username);
return Collections.emptyList(); return Collections.emptyList();
} }
......
...@@ -27,6 +27,8 @@ import org.eclipsefoundation.core.model.RequestWrapper; ...@@ -27,6 +27,8 @@ import org.eclipsefoundation.core.model.RequestWrapper;
import org.eclipsefoundation.core.service.APIMiddleware; import org.eclipsefoundation.core.service.APIMiddleware;
import org.eclipsefoundation.core.service.CachingService; import org.eclipsefoundation.core.service.CachingService;
import org.eclipsefoundation.efservices.api.models.EfUser.Eca; import org.eclipsefoundation.efservices.api.models.EfUser.Eca;
import org.eclipsefoundation.efservices.api.models.Project;
import org.eclipsefoundation.efservices.services.ProjectService;
import org.eclipsefoundation.foundationdb.client.model.PeopleDocumentData; import org.eclipsefoundation.foundationdb.client.model.PeopleDocumentData;
import org.eclipsefoundation.foundationdb.client.model.full.FullPeopleProjectData; import org.eclipsefoundation.foundationdb.client.model.full.FullPeopleProjectData;
import org.eclipsefoundation.persistence.dao.impl.DefaultHibernateDao; import org.eclipsefoundation.persistence.dao.impl.DefaultHibernateDao;
...@@ -35,10 +37,8 @@ import org.eclipsefoundation.persistence.service.FilterService; ...@@ -35,10 +37,8 @@ import org.eclipsefoundation.persistence.service.FilterService;
import org.eclipsefoundation.profile.api.GerritAPI; import org.eclipsefoundation.profile.api.GerritAPI;
import org.eclipsefoundation.profile.api.MailingListAPI; import org.eclipsefoundation.profile.api.MailingListAPI;
import org.eclipsefoundation.profile.api.PeopleAPI; import org.eclipsefoundation.profile.api.PeopleAPI;
import org.eclipsefoundation.profile.api.ProjectAPI;
import org.eclipsefoundation.profile.api.models.GerritChangeData; import org.eclipsefoundation.profile.api.models.GerritChangeData;
import org.eclipsefoundation.profile.api.models.MailingListData; import org.eclipsefoundation.profile.api.models.MailingListData;
import org.eclipsefoundation.profile.api.models.SpecProjectData;
import org.eclipsefoundation.profile.dtos.eclipseapi.GerritCount; import org.eclipsefoundation.profile.dtos.eclipseapi.GerritCount;
import org.eclipsefoundation.profile.helpers.UserMetadataHelper; import org.eclipsefoundation.profile.helpers.UserMetadataHelper;
import org.eclipsefoundation.profile.models.GerritResponse; import org.eclipsefoundation.profile.models.GerritResponse;
...@@ -70,10 +70,9 @@ public class DefaultUserMetadataService implements UserMetadataService { ...@@ -70,10 +70,9 @@ public class DefaultUserMetadataService implements UserMetadataService {
@Inject @Inject
@RestClient @RestClient
GerritAPI gerritAPI; GerritAPI gerritAPI;
@Inject
@RestClient
ProjectAPI projectAPI;
@Inject
ProjectService projectService;
@Inject @Inject
CachingService cache; CachingService cache;
@Inject @Inject
...@@ -110,7 +109,7 @@ public class DefaultUserMetadataService implements UserMetadataService { ...@@ -110,7 +109,7 @@ public class DefaultUserMetadataService implements UserMetadataService {
public MultivaluedMap<String, PeopleProject> getPersonProjects(String username) { public MultivaluedMap<String, PeopleProject> getPersonProjects(String username) {
List<FullPeopleProjectData> projects = getFullPeopleProjectsByUsername(username); List<FullPeopleProjectData> projects = getFullPeopleProjectsByUsername(username);
List<SpecProjectData> specProjects = getSpecProjects(); List<Project> specProjects = projectService.getAllSpecProjects();
// Map each project to it's projectID, check through specProjects if id matches // Map each project to it's projectID, check through specProjects if id matches
Optional<MultivaluedMap<String, PeopleProject>> results = cache.get(username, new MultivaluedMapImpl<>(), Optional<MultivaluedMap<String, PeopleProject>> results = cache.get(username, new MultivaluedMapImpl<>(),
...@@ -175,7 +174,7 @@ public class DefaultUserMetadataService implements UserMetadataService { ...@@ -175,7 +174,7 @@ public class DefaultUserMetadataService implements UserMetadataService {
Optional<List<MailingListData>> results = cache.get(username, new MultivaluedMapImpl<>(), MailingListData.class, Optional<List<MailingListData>> results = cache.get(username, new MultivaluedMapImpl<>(), MailingListData.class,
() -> mailingListAPI.getMailingListsByUsername(username)); () -> mailingListAPI.getMailingListsByUsername(username));
if (results.isEmpty()) { if (results.isEmpty()) {
LOGGER.warn("No mailing-list results for user: {}", username); LOGGER.warn("Mailing-list-API: No results for user: {}", username);
return Collections.emptyList(); return Collections.emptyList();
} }
...@@ -195,7 +194,7 @@ public class DefaultUserMetadataService implements UserMetadataService { ...@@ -195,7 +194,7 @@ public class DefaultUserMetadataService implements UserMetadataService {
LOGGER.debug("Found {} PeopleProjects for user: {}", results.size(), username); LOGGER.debug("Found {} PeopleProjects for user: {}", results.size(), username);
return results; return results;
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("Error while fetching PeopleProject data for user: {}", username, e); LOGGER.error("Error - fdndb-api: No PeopleProject results for user: {}", username, e);
return Collections.emptyList(); return Collections.emptyList();
} }
} }
...@@ -213,31 +212,13 @@ public class DefaultUserMetadataService implements UserMetadataService { ...@@ -213,31 +212,13 @@ public class DefaultUserMetadataService implements UserMetadataService {
Optional<List<PeopleDocumentData>> results = cache.get(username, new MultivaluedMapImpl<>(), Optional<List<PeopleDocumentData>> results = cache.get(username, new MultivaluedMapImpl<>(),
PeopleDocumentData.class, () -> peopleAPI.getDocuments(username)); PeopleDocumentData.class, () -> peopleAPI.getDocuments(username));
if (results.isEmpty()) { if (results.isEmpty()) {
LOGGER.warn("No PeopleDocument results for user: {}", username); LOGGER.warn("Fdndb-api: No PeopleDocument results for user: {}", username);
return Collections.emptyList(); return Collections.emptyList();
} }
return results.get(); return results.get();
} }
/**
* Queries the Project API for all spec projects. Paginates and returns all
* results.
*
* @return A List of SpecProjectData or empty.
*/
private List<SpecProjectData> getSpecProjects() {
try {
LOGGER.debug("Fetching all spec projects from the projects-api");
List<SpecProjectData> results = middleware.getAll(p -> projectAPI.getProjects(p, 1), SpecProjectData.class);
LOGGER.debug("Found {} SpecProjects", results.size());
return results;
} catch (Exception e) {
LOGGER.error("Error while fetching SpecProjects", e);
return Collections.emptyList();
}
}
/** /**
* Queries the Gerrit API for any changes made by a given user ignoring the * Queries the Gerrit API for any changes made by a given user ignoring the
* first 'x' changes, where x is the current number of tracked changes. * first 'x' changes, where x is the current number of tracked changes.
...@@ -256,7 +237,7 @@ public class DefaultUserMetadataService implements UserMetadataService { ...@@ -256,7 +237,7 @@ public class DefaultUserMetadataService implements UserMetadataService {
Optional<List<GerritChangeData>> results = cache.get(email, cacheParams, GerritChangeData.class, Optional<List<GerritChangeData>> results = cache.get(email, cacheParams, GerritChangeData.class,
() -> getAllGerritChanges(email, start)); () -> getAllGerritChanges(email, start));
if (results.isEmpty() || results.get().isEmpty()) { if (results.isEmpty() || results.get().isEmpty()) {
LOGGER.warn("No new changes beyond {} for {}", start, email); LOGGER.warn("Gerrit: No new changes beyond {} for {}", start, email);
return Collections.emptyList(); return Collections.emptyList();
} }
......
...@@ -20,7 +20,7 @@ import javax.ws.rs.core.Response; ...@@ -20,7 +20,7 @@ import javax.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.inject.RestClient; import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.eclipsefoundation.core.service.APIMiddleware.BaseAPIParameters; import org.eclipsefoundation.core.service.APIMiddleware.BaseAPIParameters;
import org.eclipsefoundation.profile.api.ProjectAPI; import org.eclipsefoundation.efservices.api.ProjectsAPI;
import org.eclipsefoundation.profile.api.models.SpecProjectData; import org.eclipsefoundation.profile.api.models.SpecProjectData;
import io.quarkus.test.Mock; import io.quarkus.test.Mock;
...@@ -28,7 +28,7 @@ import io.quarkus.test.Mock; ...@@ -28,7 +28,7 @@ import io.quarkus.test.Mock;
@Mock @Mock
@RestClient @RestClient
@ApplicationScoped @ApplicationScoped
public class MockProjectAPI implements ProjectAPI { public class MockProjectAPI implements ProjectsAPI {
private List<SpecProjectData> specProjects; private List<SpecProjectData> specProjects;
...@@ -48,4 +48,9 @@ public class MockProjectAPI implements ProjectAPI { ...@@ -48,4 +48,9 @@ public class MockProjectAPI implements ProjectAPI {
public Response getProjects(BaseAPIParameters params, int isSpecProject) { public Response getProjects(BaseAPIParameters params, int isSpecProject) {
return Response.ok(specProjects).build(); return Response.ok(specProjects).build();
} }
@Override
public Response getInterestGroups(BaseAPIParameters arg0) {
return Response.ok().build();
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment