diff --git a/.github/workflows/analysis-of-endpoint-connections.yml b/.github/workflows/analysis-of-endpoint-connections.yml new file mode 100644 index 000000000000..b842975a7102 --- /dev/null +++ b/.github/workflows/analysis-of-endpoint-connections.yml @@ -0,0 +1,39 @@ +name: Analysis-of-Endpoint-Connections + +on: + pull_request: + types: + - opened + - synchronize + paths: + - 'src/main/java/**' + - 'src/main/webapp/**' + +jobs: + show-modified-files: + timeout-minutes: 10 + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get list of modified files + run: | + git diff --name-only origin/${{ github.event.pull_request.base.ref }} HEAD > modified_files.txt + + - name: Set up JDK 21 + uses: actions/setup-java@v2 + with: + java-version: '21' + distribution: 'adopt' + + - name: Build analysis-of-endpoint-connections + run: | + ./gradlew :supporting_scripts:analysis-of-endpoint-connections:build + ./gradlew :supporting_scripts:analysis-of-endpoint-connections:shadowJar + + - name: run analysis-of-endpoint-connections + run: | + java -jar supporting_scripts/analysis-of-endpoint-connections/build/libs/analysis-of-endpoint-connections-1.0-SNAPSHOT-all.jar $(cat modified_files.txt) diff --git a/settings.gradle b/settings.gradle index a077d360727f..dc8897e1b9b1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -11,3 +11,5 @@ pluginManagement { } rootProject.name = 'Artemis' + +include 'supporting_scripts:analysis-of-endpoint-connections' diff --git a/supporting_scripts/analysis-of-endpoint-connections/build.gradle b/supporting_scripts/analysis-of-endpoint-connections/build.gradle new file mode 100644 index 000000000000..fa3484e5acd3 --- /dev/null +++ b/supporting_scripts/analysis-of-endpoint-connections/build.gradle @@ -0,0 +1,31 @@ +plugins { + id 'java' + id 'com.github.johnrengelman.shadow' version '7.1.0' +} + +group 'de.tum.in.www1.artemis' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'com.thoughtworks.qdox:qdox:2.0-M9' + implementation 'org.springframework.boot:spring-boot-starter-web:2.5.4' + testImplementation 'junit:junit:4.13.2' +} + +test { + useJUnitPlatform() +} + +jar { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + manifest { + attributes 'Main-Class': 'analysisOfEndpointConnections.AnalysisOfEndpointConnections' + } + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } +} diff --git a/supporting_scripts/analysis-of-endpoint-connections/src/main/java/analysisOfEndpointConnections/AnalysisOfEndpointConnections.java b/supporting_scripts/analysis-of-endpoint-connections/src/main/java/analysisOfEndpointConnections/AnalysisOfEndpointConnections.java new file mode 100644 index 000000000000..6a55800a98a6 --- /dev/null +++ b/supporting_scripts/analysis-of-endpoint-connections/src/main/java/analysisOfEndpointConnections/AnalysisOfEndpointConnections.java @@ -0,0 +1,75 @@ +package analysisOfEndpointConnections; + +import java.io.File; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import com.thoughtworks.qdox.JavaProjectBuilder; +import com.thoughtworks.qdox.model.JavaAnnotation; +import com.thoughtworks.qdox.model.JavaClass; +import com.thoughtworks.qdox.model.JavaMethod; + +public class AnalysisOfEndpointConnections { + + /** + * This is the main method which makes use of addNum method. + * + * @param args Unused. + */ + public static void main(String[] args) { +// String[] testArray = new String[2]; +// testArray[0] = "src/main/java/de/tum/in/www1/artemis/web/rest/tutorialgroups/TutorialGroupFreePeriodResource.java"; +// testArray[1] = "src/main/java/de/tum/in/www1/artemis/web/rest//TutorialGroupFreePeriodResource.java"; + String[] serverFiles = Arrays.stream(args).filter(filePath -> new File(filePath).exists() && filePath.endsWith(".java")).toArray(String[]::new); + + analyzeServerEndpoints(serverFiles); + } + + private static void analyzeServerEndpoints(String[] filePaths) { + final List httpMethodFullNames = List.of( + "org.springframework.web.bind.annotation.GetMapping", + "org.springframework.web.bind.annotation.PostMapping", + "org.springframework.web.bind.annotation.PutMapping", + "org.springframework.web.bind.annotation.DeleteMapping", + "org.springframework.web.bind.annotation.PatchMapping" + ); + final String requestMappingFullName = "org.springframework.web.bind.annotation.RequestMapping"; + JavaProjectBuilder builder = new JavaProjectBuilder(); + for (String filePath : filePaths) { + builder.addSourceTree(new File(filePath)); + } + + Collection classes = builder.getClasses(); + for (JavaClass javaClass : classes) { + Optional requestMappingOptional = javaClass.getAnnotations().stream() + .filter(annotation -> + annotation.getType().getFullyQualifiedName().equals(requestMappingFullName)) + .findFirst(); + for (JavaMethod method : javaClass.getMethods()) { + for (JavaAnnotation annotation : method.getAnnotations()) { + if (httpMethodFullNames.contains(annotation.getType().getFullyQualifiedName())) { + if (requestMappingOptional.isPresent()) { + System.out.println("Request Mapping: " + requestMappingOptional.get().getProperty("value")); + }; + System.out.println("Endpoint: " + method.getName()); + System.out.println("HTTP Method: " + annotation.getType().getName()); + System.out.println("Path: " + annotation.getProperty("value")); + System.out.println("Class: " + javaClass.getFullyQualifiedName()); + System.out.println("Line: " + method.getLineNumber()); + var annotations = method.getAnnotations().stream() + .filter(a -> !a.equals(annotation)) + .map(a -> a.getType().getName()).toList(); + System.out.println("Other annotations: " + annotations); + System.out.println("---------------------------------------------------"); + } + } + } + } + } + + private static void analyzeClientRESTCalls(String[] filePaths) { + + } +}