From e6c04206f42c689c18e86e60de4633ec652a0a19 Mon Sep 17 00:00:00 2001 From: Mitchell Herrijgers Date: Mon, 18 Jul 2022 10:01:49 +0200 Subject: [PATCH 1/2] Add filter to dependency check, fixes #109 --- .../aggregate/JavaAggregateIdInspection.kt | 2 +- .../aggregate/KotlinAggregateIdInspection.kt | 2 +- .../ide/plugin/support/ReportingService.kt | 2 +- .../ide/plugin/usage/AxonDependency.kt | 50 +++++++++++++++++++ .../ide/plugin/usage/AxonVersionService.kt | 23 ++++----- .../ide/plugin/util/PSiProcessingUtils.kt | 4 +- .../ide/plugin/util/ProjectUtilsKtTest.kt | 8 +-- 7 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonDependency.kt diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/inspections/aggregate/JavaAggregateIdInspection.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/inspections/aggregate/JavaAggregateIdInspection.kt index 4c14c31..eb57c0b 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/inspections/aggregate/JavaAggregateIdInspection.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/inspections/aggregate/JavaAggregateIdInspection.kt @@ -38,7 +38,7 @@ class JavaAggregateIdInspection : AbstractBaseJavaLocalInspectionTool() { if (!aClass.isAggregate()) { return null } - val entity = aClass.aggregateResolver().getEntityByName(aClass.qualifiedName!!)!! + val entity = aClass.qualifiedName?.let { aClass.aggregateResolver().getEntityByName(it) } ?: return emptyArray() if (entity.routingKey == null) { return arrayOf( manager.createProblemDescriptor( diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/inspections/aggregate/KotlinAggregateIdInspection.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/inspections/aggregate/KotlinAggregateIdInspection.kt index c51aa47..83f343f 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/inspections/aggregate/KotlinAggregateIdInspection.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/inspections/aggregate/KotlinAggregateIdInspection.kt @@ -44,7 +44,7 @@ class KotlinAggregateIdInspection : AbstractKotlinInspection() { if (!uClass.isAggregate()) { return } - val entity = uClass.aggregateResolver().getEntityByName(uClass.qualifiedName!!)!! + val entity = uClass.qualifiedName?.let { uClass.aggregateResolver().getEntityByName(it) } ?: return if (entity.routingKey == null) { holder.registerProblem( element, diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/support/ReportingService.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/support/ReportingService.kt index f4c1fc6..acf0004 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/support/ReportingService.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/support/ReportingService.kt @@ -67,7 +67,7 @@ class ReportingService { private fun Project.addLibraryVersionsToExtras() { versionService().getAxonVersions().forEach { dep -> - Sentry.setExtra(dep.name, dep.toVersionString()) + Sentry.setExtra(dep.dependency.moduleName, dep.toVersionString()) } } } diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonDependency.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonDependency.kt new file mode 100644 index 0000000..d8c4a3d --- /dev/null +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonDependency.kt @@ -0,0 +1,50 @@ +/* + * Copyright (c) (2010-2022). Axon Framework + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.axonframework.intellij.ide.plugin.usage + +enum class AxonDependency(val moduleName: String, val checkVersion: Boolean = true) { + Core("axon-core"), // Axon 2 only + Integration("axon-integration"), // Axon 2 only + SpringMessaging("axon-springmessaging"), // Axon 2 only + DistributedCommandBus("axon-distributed-commandbus"), // Axon 2 only + Spring("axon-spring"), // Axon 3 and 4 + SpringAutoconfigure("axon-spring-boot-autoconfigure"), // Axon 3 and 4 + SpringStarter("axon-spring-boot-starter"), // Axon 3 and 4 + Messaging("axon-messaging"), // Axon 4 only + EventSourcing("axon-eventsourcing"), // Axon 4 only + Modelling("axon-modelling"), // Axon 4 only + Configuration("axon-configuration"), // Axon 4 only + Test("axon-test"), // Axon 2, 3 and 4 + Metrics("axon-metrics"), // Axon 3 and 4 + Legacy("axon-legacy"), // Axon 3 and 4 + Micrometer("axon-micrometer"), // Axon 4 only + Disruptor("axon-disruptor"), // Axon 4 only + ServerConnector("axon-server-connector"), // Axon 4 only + + // Extensions, used for reporting during bugs, not for version check + Mongo("axon-mongo", false), + Mongo3("axon-mongo3", false), + Amqp("axon-amqp", false), + Jgroups("axon-jgroups", false), + Reactor("axon-reactor", false), + Kotlin("axon-kotlin", false), + Kafka("axon-kafka", false), + Multitenancy("axon-multitenancy", false), + SpringCloud("axon-springcloud", false), + Tracing("axon-tracing", false), + Cdi("axon-cdi", false), +} diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonVersionService.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonVersionService.kt index 030ab81..f12d7d2 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonVersionService.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/usage/AxonVersionService.kt @@ -27,7 +27,8 @@ import com.intellij.openapi.roots.OrderEnumerator class AxonVersionService(val project: Project) { private var enabled = false private var messageShown = false - private val regex = Regex("(axon-.*)-(\\d+)\\.(\\d+)\\.(\\d+)(.*)\\.jar") + + private val regex = Regex(".*(axon-.*)-(\\d+)\\.(\\d+)\\.(\\d+)(.*)\\.jar") init { @@ -64,13 +65,13 @@ class AxonVersionService(val project: Project) { messageShown = true } - private fun showDisabledMessage(outdatedDeps: List) { + private fun showDisabledMessage(outdatedDeps: List) { NotificationGroupManager.getInstance() .getNotificationGroup("AxonNotificationGroup") .createNotification( "Your project has an Axon Framework version older than 4. The plugin has been disabled. The specific dependencies are: " + outdatedDeps.joinToString( separator = "," - ) { it.name + "(${it.toVersionString()})" }, NotificationType.ERROR + ) { it.dependency.moduleName + "(${it.toVersionString()})" }, NotificationType.ERROR ) .notify(project) } @@ -90,13 +91,10 @@ class AxonVersionService(val project: Project) { if(useCache) { return enabled } - val axonVersions = getAxonVersions() - return axonVersions.isNotEmpty() && axonVersions.all { - it.major >= 4 - } + return getAxonVersions().outdated().isEmpty() } - private fun List.outdated() = filter { it.major < 4 } + private fun List.outdated() = filter { it.dependency.checkVersion && it.major < 4 } fun getAxonVersions() = OrderEnumerator.orderEntries(project) .librariesOnly() @@ -104,20 +102,21 @@ class AxonVersionService(val project: Project) { .classes() .roots .filter { it.presentableName.matches(regex) } - .map { + .mapNotNull { extractVersion(it.name) } - private fun extractVersion(name: String): AxonDependency { + private fun extractVersion(name: String): AxonDependencyVersion? { val match = regex.find(name)!! val (moduleName, majorVersion, minorVersion, patchVersion, remaining) = match.destructured - return AxonDependency(moduleName, + val dependency = AxonDependency.values().firstOrNull { it.moduleName == moduleName } ?: return null + return AxonDependencyVersion(dependency, Integer.parseInt(majorVersion), Integer.parseInt(minorVersion), Integer.parseInt(patchVersion), remaining) } - data class AxonDependency(val name: String, val major: Int, val minor: Int, val patch: Int, val remaining: String) { + data class AxonDependencyVersion(val dependency: AxonDependency, val major: Int, val minor: Int, val patch: Int, val remaining: String) { fun toVersionString() = "$major.$minor.$patch$remaining" } } diff --git a/src/main/kotlin/org/axonframework/intellij/ide/plugin/util/PSiProcessingUtils.kt b/src/main/kotlin/org/axonframework/intellij/ide/plugin/util/PSiProcessingUtils.kt index fd7187b..625c7ad 100644 --- a/src/main/kotlin/org/axonframework/intellij/ide/plugin/util/PSiProcessingUtils.kt +++ b/src/main/kotlin/org/axonframework/intellij/ide/plugin/util/PSiProcessingUtils.kt @@ -151,8 +151,8 @@ fun PsiElement.deadlineReferenceResolver(): DeadlineManagerReferenceResolver = p fun Project.aggregateResolver(): AggregateStructureResolver = getService(AggregateStructureResolver::class.java) fun PsiElement.aggregateResolver(): AggregateStructureResolver = project.aggregateResolver() fun Project.versionService(): AxonVersionService = getService(AxonVersionService::class.java) -fun Project.isAxonEnabled() = versionService().isAxonEnabled() -fun PsiElement.isAxonEnabled() = project.versionService().isAxonEnabled() +fun Project.isAxonEnabled() = versionService().isAxonEnabled(true) +fun PsiElement.isAxonEnabled() = project.versionService().isAxonEnabled(true) fun PsiClass?.isAggregate() = this?.hasAnnotation(AxonAnnotation.AGGREGATE_ROOT) == true diff --git a/src/test/kotlin/org/axonframework/intellij/ide/plugin/util/ProjectUtilsKtTest.kt b/src/test/kotlin/org/axonframework/intellij/ide/plugin/util/ProjectUtilsKtTest.kt index 19ac140..a24e6de 100644 --- a/src/test/kotlin/org/axonframework/intellij/ide/plugin/util/ProjectUtilsKtTest.kt +++ b/src/test/kotlin/org/axonframework/intellij/ide/plugin/util/ProjectUtilsKtTest.kt @@ -23,10 +23,10 @@ import org.axonframework.intellij.ide.plugin.AbstractAxonFixtureTestCase internal class ProjectUtilsKtTest : AbstractAxonFixtureTestCase() { fun testGetAxonDependencies() { val axonVersions = project.versionService().getAxonVersions() - assertThat(axonVersions).anySatisfy { it.name == "axon-eventsourcing" && it.major == 4 } - assertThat(axonVersions).anySatisfy { it.name == "axon-modelling" && it.major == 4 } - assertThat(axonVersions).anySatisfy { it.name == "axon-messaging" && it.major == 4 } - assertThat(axonVersions).anySatisfy { it.name == "axon-configuration" && it.major == 4 } + assertThat(axonVersions).anySatisfy { it.dependency.moduleName == "axon-eventsourcing" && it.major == 4 } + assertThat(axonVersions).anySatisfy { it.dependency.moduleName == "axon-modelling" && it.major == 4 } + assertThat(axonVersions).anySatisfy { it.dependency.moduleName == "axon-messaging" && it.major == 4 } + assertThat(axonVersions).anySatisfy { it.dependency.moduleName == "axon-configuration" && it.major == 4 } assertThat(project.versionService().isAxonEnabled()).isTrue assertThat(project.versionService().isAxonEnabled(true)).isTrue From 8a71990a0ffb6fc60666aa34ee64db234e28039b Mon Sep 17 00:00:00 2001 From: Mitchell Herrijgers Date: Mon, 18 Jul 2022 10:02:58 +0200 Subject: [PATCH 2/2] Add changelog for 0.7.3 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c18c9af..ac9f9f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ # Axon Framework plugin Changelog +## [0.7.3] + +### Fixed +- Issue where Axon version detection did not work properly, disabling the plugin while it should not. +- NPE when analyzing Kotlin files for AggregateIdentifier inspection + ## [0.7.2] ### Fixed