Skip to content

Commit

Permalink
[pinpoint-apm#11328] improve getApplicationHostinfo api
Browse files Browse the repository at this point in the history
  • Loading branch information
donghun-cho committed Aug 7, 2024
1 parent 217c9b3 commit a51e2be
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.navercorp.pinpoint.common.server.util.time;

import java.util.ArrayList;
import java.util.List;

public class BackwardRangeSplitter implements RangeSplitter {

private final static long DAY_MILLIS = 86400000L;

private final long rangeSizeMillis;
private final long multiplier;

public BackwardRangeSplitter() {
this(DAY_MILLIS * 2, 3);
}

public BackwardRangeSplitter(long rangeSizeMillis) {
this(rangeSizeMillis, 1);
}

public BackwardRangeSplitter(long rangeSizeMillis, long multiplier) {
this.rangeSizeMillis = rangeSizeMillis;
this.multiplier = multiplier;
}

@Override
public List<Range> splitRange(long from, long to) {
List<Range> ranges = new ArrayList<>();
long splitSize = rangeSizeMillis;
long splitEnd = to;
long splitStart = splitEnd - splitSize;
while (from < splitStart) {
ranges.add(Range.between(splitStart , splitEnd));

splitSize *= multiplier;
splitEnd = splitStart;
splitStart = splitEnd - splitSize;
}

ranges.add(Range.between(from, splitEnd));

return ranges;
}

@Override
public List<Range> splitRange(Range range) {
return splitRange(range.getFrom(), range.getTo());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.navercorp.pinpoint.common.server.util.time;

import java.util.List;

public interface RangeSplitter {

List<Range> splitRange(long from, long to);

List<Range> splitRange(Range range);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.navercorp.pinpoint.common.server.util.time;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.List;

public class RangeSplitterTest {

@Test
public void rangeSplitTest() {
long start = 0;
long end = 100;
long fixedRange = 100;
RangeSplitter rangeSplitter = new BackwardRangeSplitter(fixedRange);
Range originalRange = Range.between(start, end);

List<Range> result = rangeSplitter.splitRange(originalRange);

//printRangeList(result);
Assertions.assertThat(result.size()).isEqualTo(1);
}

@Test
public void rangeSplitTest1() {
long start = 0;
long end = 1000;
long fixedRange = 100;
RangeSplitter rangeSplitter = new BackwardRangeSplitter(fixedRange);
Range originalRange = Range.between(start, end);

List<Range> result = rangeSplitter.splitRange(originalRange);

//printRangeList(result);
Assertions.assertThat(result.size()).isEqualTo(10);
}

@Test
public void rangeSplitTest2() {
long start = 0;
long end = 7;
long fixedRange = 2;
long multiplier = 3;
RangeSplitter rangeSplitter = new BackwardRangeSplitter(fixedRange, multiplier);
Range originalRange = Range.between(start, end);

List<Range> result = rangeSplitter.splitRange(originalRange);

//printRangeList(result);
Assertions.assertThat(result.size()).isEqualTo(2);
Assertions.assertThat(result.get(0).getTo() - result.get(0).getFrom()).isEqualTo(2);
Assertions.assertThat(result.get(1).getTo() - result.get(1).getFrom()).isEqualTo(5);
}

@Test
public void rangeSplitTest3() {
long start = 0;
long end = 1;
long fixedRange = 2;
long multiplier = 3;
RangeSplitter rangeSplitter = new BackwardRangeSplitter(fixedRange, multiplier);
Range originalRange = Range.between(start, end);

List<Range> result = rangeSplitter.splitRange(originalRange);

//printRangeList(result);
Assertions.assertThat(result.size()).isEqualTo(1);
Assertions.assertThat(result.get(0).getTo() - result.get(0).getFrom()).isEqualTo(1);
}

private void printRangeList(List<Range> result) {
for (Range range : result) {
System.out.println(range.getFrom() + " ~ " + range.getTo());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
import com.navercorp.pinpoint.web.response.CodeResult;
import com.navercorp.pinpoint.web.service.AgentInfoService;
import com.navercorp.pinpoint.web.service.ApplicationService;
import com.navercorp.pinpoint.web.service.CacheService;
import com.navercorp.pinpoint.web.service.CommonService;
import com.navercorp.pinpoint.web.util.TagApplicationsUtils;
import com.navercorp.pinpoint.web.view.TagApplications;
import com.navercorp.pinpoint.web.vo.Application;
import com.navercorp.pinpoint.web.vo.agent.AgentInfo;
import com.navercorp.pinpoint.web.vo.agent.AgentInfoFilters;
import com.navercorp.pinpoint.web.vo.tree.ApplicationAgentHostList;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Positive;
Expand All @@ -34,7 +41,9 @@
import org.springframework.web.server.ResponseStatusException;

import java.time.Period;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

/**
* @author Taejin Koo
Expand All @@ -51,13 +60,20 @@ public class ApplicationController {

private final ApplicationService applicationService;

public ApplicationController(AgentInfoService agentInfoService, ApplicationService applicationService) {
private final CommonService commonService;
private final CacheService cacheService;

private static final String KEY = CacheService.DEFAULT_KEY;

public ApplicationController(AgentInfoService agentInfoService, ApplicationService applicationService, CommonService commonService, CacheService cacheService) {
this.agentInfoService = Objects.requireNonNull(agentInfoService, "agentInfoService");
this.applicationService = Objects.requireNonNull(applicationService, "applicationService");
this.commonService = Objects.requireNonNull(commonService, "commonService");
this.cacheService = Objects.requireNonNull(cacheService, "cacheService");
}

@GetMapping(value = "/getApplicationHostInfo")
public ApplicationAgentHostList getApplicationHostInfo (
public ApplicationAgentHostList getApplicationHostInfo(
@RequestParam(value = "offset", required = false, defaultValue = "1") @Positive int offset,
@RequestParam(value = "limit", required = false, defaultValue = "100") @Positive int limit,
@RequestParam(value = "durationDays", required = false) @PositiveOrZero Integer durationDays
Expand All @@ -70,6 +86,60 @@ public ApplicationAgentHostList getApplicationHostInfo (
return agentInfoService.getApplicationAgentHostList(offset, maxLimit, durationDaysPeriod);
}

@GetMapping(value = "/getApplicationHostInfoV2", params = "durationHours")
public ApplicationAgentHostList getApplicationHostInfoV2(
@RequestParam(value = "offset", required = false, defaultValue = "1") @Positive int offset,
@RequestParam(value = "limit", required = false, defaultValue = "100") @Positive int limit,
@RequestParam(value = "durationHours", required = false, defaultValue = "0") @PositiveOrZero int durationHours,
@RequestParam(value = "isContainer", required = false) Boolean isContainer,
@RequestParam(value = "clearCache", required = false, defaultValue = "false") boolean clearCache
) {
int maxLimit = Math.min(MAX_PAGING_LIMIT, limit);
durationHours = Math.min(MAX_DURATION_DAYS * 24, durationHours);
Predicate<AgentInfo> agentInfoFilter = createAgentInfoFilter(isContainer);

List<Application> applicationList = getApplicationListFromCache(clearCache);

return agentInfoService.getApplicationAgentHostList(offset, maxLimit, durationHours, applicationList, agentInfoFilter);
}

@GetMapping(value = "/getApplicationHostInfoV2")
public ApplicationAgentHostList getApplicationHostInfoDaysV2(
@RequestParam(value = "offset", required = false, defaultValue = "1") @Positive int offset,
@RequestParam(value = "limit", required = false, defaultValue = "100") @Positive int limit,
@RequestParam(value = "durationDays", required = false, defaultValue = "0") @PositiveOrZero int durationDays,
@RequestParam(value = "isContainer", required = false) Boolean isContainer,
@RequestParam(value = "clearCache", required = false, defaultValue = "false") boolean clearCache
) {
int maxLimit = Math.min(MAX_PAGING_LIMIT, limit);
int durationHours = Math.min(MAX_DURATION_DAYS * 24, durationDays * 24);
return getApplicationHostInfoV2(offset, maxLimit, durationHours, isContainer, clearCache);
}

private Predicate<AgentInfo> createAgentInfoFilter(Boolean isContainer) {
if (isContainer != null) {
return AgentInfoFilters.isContainer(isContainer);
}
return AgentInfoFilters.acceptAll();
}

private List<Application> getApplicationListFromCache(boolean clearCache) {
if (clearCache) {
cacheService.remove(KEY);
}

final TagApplications cachedApplications = cacheService.get(KEY);
if (cachedApplications == null) {
final List<Application> applicationList = commonService.selectAllApplicationNames();
final TagApplications tagApplications = TagApplicationsUtils.wrapApplicationList(applicationList);

cacheService.put(KEY, tagApplications);
return applicationList;
} else {
return cachedApplications.getApplicationList();
}
}

@RequestMapping(value = "/isAvailableApplicationName")
public CodeResult<String> isAvailableApplicationName(
@RequestParam("applicationName") @NotBlank String applicationName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.navercorp.pinpoint.web.service.CommonService;
import com.navercorp.pinpoint.web.util.etag.ETag;
import com.navercorp.pinpoint.web.util.etag.ETagUtils;
import com.navercorp.pinpoint.web.util.TagApplicationsUtils;
import com.navercorp.pinpoint.web.validation.NullOrNotBlank;
import com.navercorp.pinpoint.web.view.ApplicationGroup;
import com.navercorp.pinpoint.web.view.ServerTime;
Expand All @@ -32,7 +33,6 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

Expand Down Expand Up @@ -98,7 +98,7 @@ public ResponseEntity<ApplicationGroup> getApplicationGroup(


// Update atomicity between multiple nodes is not guaranteed
final TagApplications tagApplications = wrapApplicationList(applicationList);
final TagApplications tagApplications = TagApplicationsUtils.wrapApplicationList(applicationList);

cacheService.put(KEY, tagApplications);

Expand All @@ -115,19 +115,6 @@ public ResponseEntity<ApplicationGroup> getApplicationGroup(
.body(new ApplicationGroup(applicationList));
}

private static TagApplications wrapApplicationList(List<Application> applicationList) {
String tag = newTag(applicationList);
return new TagApplications(tag, applicationList);
}


private static String newTag(List<Application> applicationList) {
// Precondition : If the application list of hbase is the same,
// ETag value of multiple web servers is also the same.
// need MD5 hash (128 bit)
return String.valueOf(applicationList.hashCode());
}

private static ResponseEntity<ApplicationGroup> notModified() {
return ResponseEntity
.status(HttpStatus.NOT_MODIFIED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.navercorp.pinpoint.web.service;

import com.navercorp.pinpoint.common.server.util.time.Range;
import com.navercorp.pinpoint.web.vo.Application;
import com.navercorp.pinpoint.web.vo.agent.AgentAndStatus;
import com.navercorp.pinpoint.web.vo.agent.AgentInfo;
import com.navercorp.pinpoint.web.vo.agent.AgentInfoFilter;
Expand All @@ -35,6 +36,7 @@
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;

/**
* @author netspider
Expand All @@ -53,6 +55,8 @@ public interface AgentInfoService {

ApplicationAgentHostList getApplicationAgentHostList(int offset, int limit, Period durationDays);

ApplicationAgentHostList getApplicationAgentHostList(int offset, int limit, int durationDays, List<Application> applicationList, Predicate<AgentInfo> agentInfoPredicate);

Set<AgentAndStatus> getAgentsByApplicationName(String applicationName, long timestamp);

Set<AgentInfo> getAgentsByApplicationNameWithoutStatus(String applicationName, long timestamp);
Expand Down
Loading

0 comments on commit a51e2be

Please sign in to comment.