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

Add first GitHub entities and automatically fetch them for the leaderboard #62

Merged
merged 57 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
8df40a6
(feat): GraphQL + dot Env
GODrums Aug 18, 2024
5ff5a8b
Create GraphQL connection relations
GODrums Aug 18, 2024
8e625b3
fix: add referenced column names
GODrums Aug 18, 2024
bdcca5b
Merge branch 'develop' into feature/github-graphql-artemis
FelixTJDietrich Aug 20, 2024
28c226c
Replace .env with application-local.yml
GODrums Aug 20, 2024
45a6140
fix: transient value error
GODrums Aug 20, 2024
45f228d
Rework for Github API
GODrums Aug 21, 2024
d20d7a5
Merge branch 'develop' into feature/github-graphql-artemis
FelixTJDietrich Aug 23, 2024
37d1d2b
Rework repo fetch
GODrums Aug 24, 2024
78db6d2
Add endpoints for entities
GODrums Aug 25, 2024
fbb09e8
Add entity constructors
GODrums Aug 26, 2024
bae8980
table names to singular
GODrums Aug 28, 2024
d5711f2
replace list with set
GODrums Aug 28, 2024
de9adc4
Add cascade types for actor relations
GODrums Aug 28, 2024
4a372f1
Directly init relation sets
GODrums Aug 28, 2024
85f9e4c
Improve toString printing
GODrums Aug 28, 2024
8a8381b
Replace toString with annotations
GODrums Aug 28, 2024
21d3f7f
Prefer nonnull over nullable column
GODrums Aug 28, 2024
7474b78
Rename Actor, Pullrequest and Comment
GODrums Aug 28, 2024
05ed344
Add user name attribute
GODrums Aug 28, 2024
5b03982
Introduce DTO for user
GODrums Aug 29, 2024
567df15
Replace logger classes
GODrums Aug 29, 2024
1faa0dc
Create GHIssueState enum
GODrums Aug 29, 2024
930a3ef
Deleted unused classes
GODrums Aug 29, 2024
f629070
Remove more unused code
GODrums Aug 29, 2024
6e6b166
Remove github_id from entities
GODrums Aug 29, 2024
7d8df65
Improve entity comments
GODrums Aug 29, 2024
9121e61
Add more DTOs and Superclass
GODrums Aug 30, 2024
322702e
Merge branch 'develop' into feature/github-graphql-artemis
FelixTJDietrich Aug 30, 2024
06528e8
fix indentiation of application.yml
FelixTJDietrich Aug 30, 2024
b58eaea
Merge branch 'develop' into feature/github-graphql-artemis
FelixTJDietrich Aug 30, 2024
bbb2ef7
Implement feedback from review
GODrums Aug 30, 2024
f6b9e7f
Merge branch 'feature/github-graphql-artemis' of https://github.com/l…
GODrums Aug 30, 2024
b93b665
Merge branch 'develop' into feature/github-graphql-artemis
FelixTJDietrich Aug 30, 2024
a9a2410
Improve Entity generation
GODrums Aug 30, 2024
698da27
Merge branch 'feature/github-graphql-artemis' of https://github.com/l…
GODrums Aug 30, 2024
eab0543
Refactor converts with BaseGitServiceEntityConverter
GODrums Aug 30, 2024
cf50f37
Add id to DTOs
GODrums Aug 30, 2024
f9af54a
Add more Repository attributes
GODrums Aug 31, 2024
79a1194
Refactor github sync with cron
GODrums Aug 31, 2024
3588ed7
rename files and pullrequest
FelixTJDietrich Aug 31, 2024
17e6528
Rename scheduler
GODrums Aug 31, 2024
22ead12
Change repositories to fetch
GODrums Aug 31, 2024
e23c516
Redo pullrequest naming
GODrums Sep 1, 2024
3571d40
Make converter services
GODrums Sep 1, 2024
87a2620
Delete EntityNotFoundException
GODrums Sep 1, 2024
5b99ac1
Change to @Component
GODrums Sep 1, 2024
827cb8a
Delete Pullrequest.java
GODrums Sep 2, 2024
8457374
Delete PullrequestRepository.java
GODrums Sep 2, 2024
55e0486
Recommit correct casing files
GODrums Sep 2, 2024
e12ed62
Add default value for ghAuthToken
GODrums Sep 2, 2024
ce402ec
Create a non-environement ghAuthToken
GODrums Sep 2, 2024
21704cf
New OpenAPI specs
GODrums Sep 2, 2024
1530549
Execute generate:api:application-server-client
GODrums Sep 2, 2024
40dfc87
Execute generate:api
GODrums Sep 2, 2024
9b6ca82
Regenerate API from Mac
GODrums Sep 2, 2024
2c822f4
Another openapi regenerate
GODrums Sep 2, 2024
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
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
.venv
.DS_Store

# Idea files
.idea/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down Expand Up @@ -162,4 +165,6 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

node_modules/
node_modules/

application-local.yml
58 changes: 36 additions & 22 deletions server/application-server/HELP.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,53 @@
# Getting Started

### Local development

The Spring Boot Maven Plugin supports running your application with a local development environment. To do this, you can use the `spring-boot:run` goal:

```shell
mvn spring-boot:run
```

This will start your application in a local development environment. You can access the application at `http://localhost:8080`.

Setting environment variables works through profile-based `application.yml` files. For local development, create a `application-local.yml` file overwriting the original properties. See [Using the Plugin :: Spring Boot](https://docs.spring.io/spring-boot/maven-plugin/using.html#using.overriding-command-line) for more information.

### Reference Documentation

For further reference, please consider the following sections:

* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.3.2/maven-plugin/reference/html/)
* [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.3.2/maven-plugin/reference/html/#build-image)
* [Docker Compose Support](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#features.docker-compose)
* [Spring Boot DevTools](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#using.devtools)
* [Spring Web](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#web)
* [Spring Security](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#web.security)
* [Spring Data JPA](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#data.sql.jpa-and-spring-data)
* [Spring Boot Actuator](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#actuator)
* [Liquibase Migration](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#howto.data-initialization.migration-tool.liquibase)
* [OAuth2 Client](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#web.security.oauth2.client)
* [OAuth2 Resource Server](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#web.security.oauth2.server)
- [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
- [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.3.2/maven-plugin/reference/html/)
- [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.3.2/maven-plugin/reference/html/#build-image)
- [Docker Compose Support](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#features.docker-compose)
- [Spring Boot DevTools](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#using.devtools)
- [Spring Web](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#web)
- [Spring Security](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#web.security)
- [Spring Data JPA](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#data.sql.jpa-and-spring-data)
- [Spring Boot Actuator](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#actuator)
- [Liquibase Migration](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#howto.data-initialization.migration-tool.liquibase)
- [OAuth2 Client](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#web.security.oauth2.client)
- [OAuth2 Resource Server](https://docs.spring.io/spring-boot/docs/3.3.2/reference/htmlsingle/index.html#web.security.oauth2.server)

### Guides

The following guides illustrate how to use some features concretely:

* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
* [Securing a Web Application](https://spring.io/guides/gs/securing-web/)
* [Spring Boot and OAuth2](https://spring.io/guides/tutorials/spring-boot-oauth2/)
* [Authenticating a User with LDAP](https://spring.io/guides/gs/authenticating-ldap/)
* [Accessing Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/)
* [Building a RESTful Web Service with Spring Boot Actuator](https://spring.io/guides/gs/actuator-service/)
- [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
- [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
- [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
- [Securing a Web Application](https://spring.io/guides/gs/securing-web/)
- [Spring Boot and OAuth2](https://spring.io/guides/tutorials/spring-boot-oauth2/)
- [Authenticating a User with LDAP](https://spring.io/guides/gs/authenticating-ldap/)
- [Accessing Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/)
- [Building a RESTful Web Service with Spring Boot Actuator](https://spring.io/guides/gs/actuator-service/)

### Docker Compose support

This project contains a Docker Compose file named `compose.yaml`.
In this file, the following services have been defined:

* postgres: [`postgres:latest`](https://hub.docker.com/_/postgres)
- postgres: [`postgres:latest`](https://hub.docker.com/_/postgres)

Please review the tags of the used images and set them to the same as you're running in production.

Expand All @@ -42,4 +57,3 @@ Due to Maven's design, elements are inherited from the parent POM to the project
While most of the inheritance is fine, it also inherits unwanted elements like `<license>` and `<developers>` from the parent.
To prevent this, the project POM contains empty overrides for these elements.
If you manually switch to a different parent and actually want the inheritance, you need to remove those overrides.

12 changes: 12 additions & 0 deletions server/application-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
</scm>
<properties>
<java.version>21</java.version>
<app.profiles>local,dev</app.profiles>
GODrums marked this conversation as resolved.
Show resolved Hide resolved
</properties>
<dependencies>
<dependency>
Expand Down Expand Up @@ -120,6 +121,16 @@
<artifactId>spring-modulith-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>github-api</artifactId>
<version>1.324</version>
</dependency>
<dependency>
<groupId>io.hypersistence</groupId>
<artifactId>hypersistence-utils-hibernate-63</artifactId>
<version>3.8.2</version>
</dependency>
</dependencies>

<dependencyManagement>
Expand Down Expand Up @@ -158,6 +169,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<profiles>${app.profiles}</profiles>
<jvmArguments>-Dspring.application.admin.enabled=true</jvmArguments>
<excludes>
<exclude>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package de.tum.in.www1.hephaestus;

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

import org.hibernate.integrator.spi.Integrator;
import org.hibernate.jpa.boot.spi.IntegratorProvider;

import de.tum.in.www1.hephaestus.codereview.comment.IssueCommentDTO;
import de.tum.in.www1.hephaestus.codereview.pullrequest.PullRequestDTO;
import de.tum.in.www1.hephaestus.codereview.repository.RepositoryDTO;
import de.tum.in.www1.hephaestus.codereview.user.UserDTO;
import io.hypersistence.utils.hibernate.type.util.ClassImportIntegrator;

public class ClassImportIntegratorIntegratorProvider implements IntegratorProvider {

@Override
public List<Integrator> getIntegrators() {
// Accessible DTOs
@SuppressWarnings("rawtypes")
List<Class> classes = new ArrayList<>();
classes.add(UserDTO.class);
FelixTJDietrich marked this conversation as resolved.
Show resolved Hide resolved
classes.add(PullRequestDTO.class);
classes.add(IssueCommentDTO.class);
classes.add(RepositoryDTO.class);

return List.of(new ClassImportIntegrator(classes));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package de.tum.in.www1.hephaestus;

import java.util.Arrays;
import java.util.List;

import org.springframework.context.annotation.Bean;
Expand All @@ -20,14 +19,13 @@ public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.authorizeHttpRequests(authorizeRequests -> authorizeRequests
.requestMatchers("/admin/**").authenticated()
.anyRequest().permitAll()
)
.formLogin(Customizer.withDefaults())
.logout(Customizer.withDefaults());
.csrf(csrf -> csrf.disable())
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.authorizeHttpRequests(authorizeRequests -> authorizeRequests
.requestMatchers("/admin/**").authenticated()
.anyRequest().permitAll())
.formLogin(Customizer.withDefaults())
.logout(Customizer.withDefaults());

return http.build();
}
Expand All @@ -38,7 +36,7 @@ CorsConfigurationSource corsConfigurationSource() {
configuration.applyPermitDefaultValues();
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**",configuration);
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package de.tum.in.www1.hephaestus.codereview.base;

import java.time.OffsetDateTime;

import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@MappedSuperclass
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public abstract class BaseGitServiceEntity {
@Id
protected Long id;

protected OffsetDateTime createdAt;

protected OffsetDateTime updatedAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package de.tum.in.www1.hephaestus.codereview.base;

import org.kohsuke.github.GHObject;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Date;

@ReadingConverter
public abstract class BaseGitServiceEntityConverter<S extends GHObject, T extends BaseGitServiceEntity>
implements Converter<S, T> {

private static final Logger logger = LoggerFactory.getLogger(BaseGitServiceEntityConverter.class);

protected void convertBaseFields(S source, T target) {
if (source == null || target == null) {
throw new IllegalArgumentException("Source and target must not be null");
}

// Map common fields
target.setId(source.getId());

try {
target.setCreatedAt(convertToOffsetDateTime(source.getCreatedAt()));
} catch (IOException e) {
logger.error("Failed to convert createdAt field for source {}: {}", source.getId(), e.getMessage());
target.setCreatedAt(null);
}

try {
target.setUpdatedAt(convertToOffsetDateTime(source.getUpdatedAt()));
} catch (IOException e) {
logger.error("Failed to convert updatedAt field for source {}: {}", source.getId(), e.getMessage());
target.setUpdatedAt(null);
}
}

private OffsetDateTime convertToOffsetDateTime(Date date) {
return date != null ? date.toInstant().atOffset(ZoneOffset.UTC) : null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package de.tum.in.www1.hephaestus.codereview.comment;

import jakarta.persistence.Table;

import org.springframework.lang.NonNull;

import de.tum.in.www1.hephaestus.codereview.base.BaseGitServiceEntity;
import de.tum.in.www1.hephaestus.codereview.pullrequest.PullRequest;
import de.tum.in.www1.hephaestus.codereview.user.User;
import jakarta.persistence.Basic;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Lob;
import jakarta.persistence.ManyToOne;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Entity
@Table(name = "issue_comment")
@Getter
@Setter
@NoArgsConstructor
FelixTJDietrich marked this conversation as resolved.
Show resolved Hide resolved
@ToString(callSuper = true)
public class IssueComment extends BaseGitServiceEntity {
@NonNull
@Lob
@Basic(fetch = FetchType.EAGER)
private String body;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_id")
@ToString.Exclude
private User author;

@ManyToOne(optional = false)
@JoinColumn(name = "pullrequest_id", referencedColumnName = "id")
@ToString.Exclude
private PullRequest pullRequest;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package de.tum.in.www1.hephaestus.codereview.comment;

import org.kohsuke.github.GHIssueComment;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

import de.tum.in.www1.hephaestus.codereview.base.BaseGitServiceEntityConverter;

@Service
GODrums marked this conversation as resolved.
Show resolved Hide resolved
public class IssueCommentConverter extends BaseGitServiceEntityConverter<GHIssueComment, IssueComment> {

@Override
public IssueComment convert(@NonNull GHIssueComment source) {
IssueComment comment = new IssueComment();
GODrums marked this conversation as resolved.
Show resolved Hide resolved
convertBaseFields(source, comment);
comment.setBody(source.getBody());
return comment;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package de.tum.in.www1.hephaestus.codereview.comment;

import com.fasterxml.jackson.annotation.JsonInclude;

import de.tum.in.www1.hephaestus.codereview.pullrequest.PullRequestDTO;
import de.tum.in.www1.hephaestus.codereview.user.UserDTO;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public record IssueCommentDTO(Long id, String body, String createdAt, String updatedAt, UserDTO author,
PullRequestDTO pullRequest) {
public IssueCommentDTO(Long id, String body, String createdAt, String updatedAt) {
this(id, body, createdAt, updatedAt, null, null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package de.tum.in.www1.hephaestus.codereview.comment;

import org.springframework.data.jpa.repository.JpaRepository;

public interface IssueCommentRepository extends JpaRepository<IssueComment, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package de.tum.in.www1.hephaestus.codereview.pullrequest;

public enum IssueState {
CLOSED, OPEN
}
Loading
Loading