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

create detection llm endpoint #232

Open
wants to merge 10 commits into
base: 223-creating-activity-dashboard
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequestRepository;
import de.tum.in.www1.hephaestus.gitprovider.user.UserRepository;
import jakarta.transaction.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -46,7 +48,7 @@ public ActivityDTO getActivity(String login) {
pullRequestBadPracticeRepository.findAssignedByLoginAndOpen(login);

Map<PullRequest, List<PullRequestBadPracticeDTO>> pullRequestBadPracticesMap = openPulLRequestBadPractices
.stream()
.stream().filter(pullRequestBadPractice -> !pullRequestBadPractice.isResolved())
.collect(
Collectors.groupingBy(
PullRequestBadPractice::getPullrequest,
Expand All @@ -61,35 +63,30 @@ public ActivityDTO getActivity(String login) {
.map(pullRequest ->
PullRequestWithBadPracticesDTO.fromPullRequest(
pullRequest,
pullRequestBadPracticesMap.getOrDefault(
pullRequest,
List.of(
new PullRequestBadPracticeDTO("Unchecked checkbox.", "The checkbox is not checked.", false)
)
)
pullRequestBadPracticesMap.getOrDefault(pullRequest, List.of())
)
)
.collect(Collectors.toList());

return new ActivityDTO(openPullRequestsWithBadPractices);
}

@Transactional
public List<PullRequestBadPracticeDTO> detectBadPractices(String login) {
logger.info("Detecting bad practices for user with login: {}", login);

userRepository.findByLogin(login).orElseThrow(() -> new IllegalArgumentException("User not found"));

List<PullRequest> pullRequests = pullRequestRepository.findAssignedByLoginAndStates(
login,
Set.of(Issue.State.OPEN)
);

return pullRequests
.stream()
.map(pullRequestBadPracticeDetector::detectAndSyncBadPractices)
.flatMap(List::stream)
.map(PullRequestBadPracticeDTO::fromPullRequestBadPractice)
.collect(Collectors.toList());
List<PullRequestBadPractice> existingBadPractices = pullRequestBadPracticeRepository.findAssignedByLoginAndOpen(login);
existingBadPractices.forEach(existingBadPractice -> existingBadPractice.setResolved(true));
pullRequestBadPracticeRepository.saveAll(existingBadPractices);

List<PullRequestBadPractice> detectedBadPractices = new ArrayList<>();
for (PullRequest pullRequest : pullRequests) {
detectedBadPractices.addAll(pullRequestBadPracticeDetector.detectAndSyncBadPractices(pullRequest));
}
return detectedBadPractices.stream().map(PullRequestBadPracticeDTO::fromPullRequestBadPractice).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

import de.tum.in.www1.hephaestus.activity.PullRequestBadPracticeRepository;
import de.tum.in.www1.hephaestus.activity.model.PullRequestBadPractice;
import de.tum.in.www1.hephaestus.config.BadPracticeDetectorConfig.BadPracticeDetectorService;
import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequest;
import java.util.LinkedList;
import java.util.List;

import de.tum.in.www1.hephaestus.intelligenceservice.model.BadPractice;
import de.tum.in.www1.hephaestus.intelligenceservice.model.DetectorRequest;
import de.tum.in.www1.hephaestus.intelligenceservice.model.DetectorResponse;
import jakarta.transaction.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -17,13 +24,34 @@ public class PullRequestBadPracticeDetector {
@Autowired
private PullRequestBadPracticeRepository pullRequestBadPracticeRepository;

@Autowired
private BadPracticeDetectorService detectorApi;

public List<PullRequestBadPractice> detectAndSyncBadPractices(PullRequest pullRequest) {
logger.info("Detecting bad practices for pull request: {}.", pullRequest.getId());
logger.info("Detecting bad practices for pull request: {}", pullRequest.getId());
DetectorRequest detectorRequest = new DetectorRequest();
detectorRequest.setDescription(pullRequest.getBody());
detectorRequest.setTitle(pullRequest.getTitle());
DetectorResponse detectorResponse = detectorApi.detectDetectorPost(detectorRequest);

List<PullRequestBadPractice> detectedBadPractices = new LinkedList<>();

for (BadPractice badPractice : detectorResponse.getBadPractices()) {
detectedBadPractices.add(handleDetectedBadPractices(pullRequest, badPractice));
}

logger.info("Detected {} bad practices for pull request: {}", detectedBadPractices.size(), pullRequest.getId());
return detectedBadPractices;
}

List<PullRequestBadPractice> existingBadPractices = pullRequestBadPracticeRepository.findByPullRequestId(
pullRequest.getId()
);
@Transactional
protected PullRequestBadPractice handleDetectedBadPractices(PullRequest pullRequest, BadPractice badPractice) {

return existingBadPractices;
PullRequestBadPractice pullRequestBadPractice = new PullRequestBadPractice();
pullRequestBadPractice.setTitle(badPractice.getTitle());
pullRequestBadPractice.setDescription(badPractice.getDescription());
pullRequestBadPractice.setPullrequest(pullRequest);
pullRequestBadPractice.setResolved(false);
return pullRequestBadPracticeRepository.save(pullRequestBadPractice);
}
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
package de.tum.in.www1.hephaestus.activity.model;

import de.tum.in.www1.hephaestus.gitprovider.pullrequest.PullRequest;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@Setter
@NoArgsConstructor
@ToString
@Table(name="pullrequestbadpractice")
public class PullRequestBadPractice {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NonNull
private String title;

@NonNull
private String description;

@NonNull
@ManyToOne
@JoinColumn(name = "pullrequest_id")
private PullRequest pullrequest;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package de.tum.in.www1.hephaestus.config;

import de.tum.in.www1.hephaestus.intelligenceservice.ApiClient;
import de.tum.in.www1.hephaestus.intelligenceservice.api.DetectorApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BadPracticeDetectorConfig {

@Value("${hephaestus.intelligence-service.url}")
private String badPracticeDetectorUrl;

@Bean
public BadPracticeDetectorService badPracticeDetectorService() {
return new BadPracticeDetectorService();
}

public class BadPracticeDetectorService extends DetectorApi {

public BadPracticeDetectorService() {
super(new ApiClient().setBasePath(badPracticeDetectorUrl));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.List;
import java.util.Optional;
import java.util.Set;

import jakarta.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
Expand All @@ -20,6 +22,7 @@ SELECT MIN(p.createdAt)
)
Optional<OffsetDateTime> firstContributionByAuthorLogin(@Param("authorLogin") String authorLogin);

@Transactional
@Query(
"""
SELECT p
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package de.tum.in.www1.hephaestus.intelligenceservice.api;

import de.tum.in.www1.hephaestus.intelligenceservice.ApiClient;
import de.tum.in.www1.hephaestus.intelligenceservice.BaseApi;

import de.tum.in.www1.hephaestus.intelligenceservice.model.DetectorRequest;
import de.tum.in.www1.hephaestus.intelligenceservice.model.DetectorResponse;
import de.tum.in.www1.hephaestus.intelligenceservice.model.HTTPValidationError;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.7.0")
public class DetectorApi extends BaseApi {

public DetectorApi() {
super(new ApiClient());
}

public DetectorApi(ApiClient apiClient) {
super(apiClient);
}

/**
* Detect bad practices given rules.
*
* <p><b>200</b> - Successful Response
* <p><b>422</b> - Validation Error
* @param detectorRequest (required)
* @return DetectorResponse
* @throws RestClientException if an error occurs while attempting to invoke the API
*/
public DetectorResponse detectDetectorPost(DetectorRequest detectorRequest) throws RestClientException {
return detectDetectorPostWithHttpInfo(detectorRequest).getBody();
}

/**
* Detect bad practices given rules.
*
* <p><b>200</b> - Successful Response
* <p><b>422</b> - Validation Error
* @param detectorRequest (required)
* @return ResponseEntity&lt;DetectorResponse&gt;
* @throws RestClientException if an error occurs while attempting to invoke the API
*/
public ResponseEntity<DetectorResponse> detectDetectorPostWithHttpInfo(DetectorRequest detectorRequest) throws RestClientException {
Object localVarPostBody = detectorRequest;

// verify the required parameter 'detectorRequest' is set
if (detectorRequest == null) {
throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'detectorRequest' when calling detectDetectorPost");
}


final MultiValueMap<String, String> localVarQueryParams = new LinkedMultiValueMap<String, String>();
final HttpHeaders localVarHeaderParams = new HttpHeaders();
final MultiValueMap<String, String> localVarCookieParams = new LinkedMultiValueMap<String, String>();
final MultiValueMap<String, Object> localVarFormParams = new LinkedMultiValueMap<String, Object>();

final String[] localVarAccepts = {
"application/json"
};
final List<MediaType> localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
final String[] localVarContentTypes = {
"application/json"
};
final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);

String[] localVarAuthNames = new String[] { };

ParameterizedTypeReference<DetectorResponse> localReturnType = new ParameterizedTypeReference<DetectorResponse>() {};
return apiClient.invokeAPI("/detector/", HttpMethod.POST, Collections.<String, Object>emptyMap(), localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType);
}

@Override
public <T> ResponseEntity<T> invokeAPI(String url, HttpMethod method, Object request, ParameterizedTypeReference<T> returnType) throws RestClientException {
String localVarPath = url.replace(apiClient.getBasePath(), "");
Object localVarPostBody = request;

final Map<String, Object> uriVariables = new HashMap<String, Object>();
final MultiValueMap<String, String> localVarQueryParams = new LinkedMultiValueMap<String, String>();
final HttpHeaders localVarHeaderParams = new HttpHeaders();
final MultiValueMap<String, String> localVarCookieParams = new LinkedMultiValueMap<String, String>();
final MultiValueMap<String, Object> localVarFormParams = new LinkedMultiValueMap<String, Object>();

final String[] localVarAccepts = {
"application/json"
};
final List<MediaType> localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
final String[] localVarContentTypes = {
"application/json"
};
final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);

String[] localVarAuthNames = new String[] { };

return apiClient.invokeAPI(localVarPath, method, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, returnType);
}
}
Loading
Loading