Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SELV3-785: Dashboard reports definition #10

Merged
merged 2 commits into from
Jan 8, 2025
Merged

Conversation

mgrochalskisoldevelo
Copy link
Contributor

Added dashboard reports definition:

Endpoints:

/api/reports/dashboardReports

  • GET /{id}
  • GET
  • GET /availableReports
  • DELETE /{id}
  • POST
  • PUT /{id}

/api/reports/reportCategories

  • GET /{id}
  • GET
  • POST
  • PUT /{id}
  • DELETE

Copy link
Contributor

@pwargulak pwargulak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments.


package org.openlmis.report.i18n;

public class DashboardReportMessageKeys extends MessageKeys {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to change this pattern, in my opinion this is super confusing and plain bad.
I propose to type the key text as-is, ex:

public class DashboardReportMessageKeys {
  public static final String ERROR_DASHBOARD_REPORT_NAME_DUPLICATED = "report.error.servicedashboardReport.name.duplicated";
  public static final String ERROR_DASHBOARD_REPORT_NOT_FOUND = "report.error.servicedashboardReport.notFound";
  // ...
}


package org.openlmis.report.i18n;

public class ReportCategoryMessageKeys extends ReportingMessageKeys {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See DashboardReportMessageKeys comment.

@@ -74,5 +75,10 @@ public String obtainAccessToken() {
void setRestTemplate(RestOperations restTemplate) {
this.restTemplate = restTemplate;
}

@CacheEvict(cacheNames = "token", allEntries = true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this 'token' cache anywhere.
Is org.springframework.cache.annotation.Cacheable missing from obtainAccessToken?

Also, I see this caching not being used in core services - do we know if this is any perf impro we can move later to core services?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is something that I took while moving methods from other services. However now I verified and it is not being used in both. For the time being I will remove it.

import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;

public interface DashboardReportRepository
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some methods here, have parameters annotated with @param some not, and I can't find a pattern.

}
}

protected <P> void runWithRetryAndTokenRetry(HttpTask<P> task) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this method (but in different service) had some bad consequences in Malawi where a call from Requisition to Stock Management would be fired twice (as the 1st would timeout), and added twice as much data to DB, and made us wait twice the time to know it fails.

I think this retry logic (for 4xx and 5xx) might be a bad design.

The token expiration is fine, but do we know why we retry on any 4xx and 5xx?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. I don't think we need 4xx 5xx retries. I will leave runWithTokenRetry only and change method type to void since the response is not being used.

} catch (DataIntegrityViolationException ex) {
throw new ValidationMessageException(new Message(
DashboardReportMessageKeys.ERROR_DASHBOARD_REPORT_NAME_DUPLICATED, dto.getName()), ex);
} catch (Exception ex) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would split this two saves in own try-catch - now 'a random' error from saveDashboardReport would be reported as 'count not save right'.

public DashboardReportDto createDashboardReport(DashboardReportDto dto) {
permissionService.canManageReports();

boolean reportExists = dashboardReportRepository.findByName(dto.getName()).isPresent();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to use boolean existsByName() pattern - again not much of performance gain in this scenario, but I think it's just a good practice.

* @return New RightDto
*/
private RightDto createRight(String dashboardReportName) {
String transformedName = dashboardReportName.trim().toUpperCase().replace(" ", "_") + "_RIGHT";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does a right name must be a valid file.properties key? If so, I would made small class with something like transformToPropKey - maybe there is already such lib - because there are more illegal characters then just a 'space'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Good observation.

public ReportCategoryDto createReportCategory(ReportCategoryDto dto) {
permissionService.canManageReportCategories();

reportCategoryRepository.findByName(dto.getName())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest reportCategoryRepository.existsByName(dto.getName()))

.orElseThrow(() -> new NotFoundMessageException(
ReportCategoryMessageKeys.ERROR_REPORT_CATEGORY_NOT_FOUND));

reportCategoryRepository.findByName(dto.getName())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be solved by single Spring Data method: boolean existsByIdIsNotAndName(id, name); or similar.

Copy link

sonarqubecloud bot commented Jan 8, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@mgrochalskisoldevelo mgrochalskisoldevelo merged commit 3063f72 into master Jan 8, 2025
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants