diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 18f14a67..69598b54 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -22,15 +22,15 @@ jobs: - temurin - zulu java-version: - - 8 - - 11 + - 17 + - 21 include: - platform: windows-latest java-distribution: adopt-hotspot - java-version: 11 + java-version: 17 - platform: macos-latest java-distribution: adopt-hotspot - java-version: 11 + java-version: 17 runs-on: ${{ matrix.platform }} timeout-minutes: 5 steps: diff --git a/.java-version b/.java-version deleted file mode 100644 index 62593409..00000000 --- a/.java-version +++ /dev/null @@ -1 +0,0 @@ -1.8 diff --git a/build.gradle b/build.gradle index 6b7de371..3186a3aa 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,7 @@ plugins { id 'net.researchgate.release' version '3.1.0' // TODO: wait for https://github.com/hierynomus/license-gradle-plugin/issues/161 // id "com.github.hierynomus.license" version "0.14.0" apply false + id 'maven-publish' } apply plugin: 'java' @@ -10,7 +11,7 @@ description = "Notifications infrastucture for Apereo uPortal" subprojects { apply plugin: 'java' - apply plugin: 'maven' + apply plugin: 'maven-publish' apply plugin: 'signing' // TODO: wait for https://github.com/hierynomus/license-gradle-plugin/issues/161 // apply plugin: 'license' @@ -39,7 +40,8 @@ subprojects { // exclude "**/*.json" // } - sourceCompatibility = 1.8 + sourceCompatibility = 17 + targetCompatibility = 17 /* Release Management * @@ -49,12 +51,12 @@ subprojects { publishingUsername = project.hasProperty('ossrhUsername') ? project.getProperty('ossrhUsername') : "" publishingPassword = project.hasProperty('ossrhPassword') ? project.getProperty('ossrhPassword') : "" } - task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' + tasks.register('javadocJar', Jar) { + archiveClassifier = 'javadoc' from javadoc.destinationDir } - task sourcesJar(type: Jar, dependsOn: classes) { - classifier 'sources' + tasks.register('sourcesJar', Jar) { + archiveClassifier = 'sources' from sourceSets.main.allSource } tasks.withType(Javadoc) { @@ -74,48 +76,12 @@ subprojects { required { gradle.taskGraph.hasTask('uploadArchives') } sign configurations.archives } - uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: publishingUsername, password: publishingPassword) - } - - pom.project { - name 'NotificationPortlet' - description 'Content objects for displaying important notices from campus ' + - 'systems in uPortal based on Web Components and JSR-286 (Portlet 2.0)' - url 'https://github.com/Jasig/NotificationPortlet' - - scm { - connection 'scm:git:git://github.com/Jasig/NotificationPortlet.git' - url 'https://github.com/Jasig/NotificationPortlet' - } - - licenses { - license { - name 'The Apache License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - } - } - - developers { - developer { - organization 'NotificationPortlet Developers' - organizationUrl 'https://github.com/Jasig/NotificationPortlet/graphs/contributors' - } - } - } - } - } - } release { tagTemplate = 'v${version}' // Looks like it should be a GString, but not necessary git { requireBranch.set('') } } - afterReleaseBuild.dependsOn uploadArchives + afterReleaseBuild.dependsOn publish } diff --git a/gradle.properties b/gradle.properties index a11f596f..dd4a8151 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,8 @@ group=org.jasig.portlet.notification version=4.8.1-SNAPSHOT -# Matches (apparently) Spring Boot 1.5.10.RELEASE -springVersion=4.3.30.RELEASE -springSecurityVersion=4.2.9.RELEASE +springVersion=5.3.31 +springSecurityVersion=5.7.11 springSecurityOAuth2Version=2.5.2.RELEASE # Dependency Versions diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 53b9e380..a5952066 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/notification-portlet-api/build.gradle b/notification-portlet-api/build.gradle index 84ab1636..eb711426 100644 --- a/notification-portlet-api/build.gradle +++ b/notification-portlet-api/build.gradle @@ -1,48 +1,54 @@ description = "Simple data model for Notifications used in integrations" dependencies { - compile "com.fasterxml.jackson.core:jackson-annotations:${jacksonVersion}" - compile "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}" - compile "com.fasterxml.jackson.core:jackson-databind:${jacksonDatabindVersion}" - compile "commons-lang:commons-lang:${commonsLangVersion}" - compile "org.slf4j:slf4j-api:${slf4jVersion}" - compile "javax.annotation:javax.annotation-api:${annotationApiVersion}" - compile "javax.xml.bind:jaxb-api:${jaxbApiVersion}" + implementation "com.fasterxml.jackson.core:jackson-annotations:${jacksonVersion}" + implementation "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}" + implementation "com.fasterxml.jackson.core:jackson-databind:${jacksonDatabindVersion}" + implementation "commons-lang:commons-lang:${commonsLangVersion}" + implementation "org.slf4j:slf4j-api:${slf4jVersion}" + implementation "javax.annotation:javax.annotation-api:${annotationApiVersion}" + implementation "javax.xml.bind:jaxb-api:${jaxbApiVersion}" compileOnly "org.projectlombok:lombok:${lombokVersion}" annotationProcessor "org.projectlombok:lombok:${lombokVersion}" compileOnly "${portletApiDependency}" compileOnly "javax.servlet:servlet-api:${servletApiVersion}" } -uploadArchives{ - repositories { - mavenDeployer { - pom.project { - name 'notification-portlet-api' - packaging 'jar' - // optionally artifactId can be defined here - description 'API jar for Apereo NotificationPortlet' - url 'https://github.com/Jasig/NotificationPortlet' +publishing { + publications { + create('mavenJava', MavenPublication) { + from components.java + + pom { + name = 'notification-portlet-api' + packaging = 'jar' + description = 'API jar for Apereo NotificationPortlet' + url = 'https://github.com/Jasig/NotificationPortlet' scm { - connection 'scm:git@github.com:Jasig/NotificationPortlet.git' - url 'https://github.com/Jasig/NotificationPortlet' + connection = 'scm:git@github.com:Jasig/NotificationPortlet.git' + url = 'https://github.com/Jasig/NotificationPortlet' } licenses { license { - name 'The Apache License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' } } developers { developer { - organization 'uPortal Developers' - organizationUrl 'https://github.com/Jasig/uPortal/graphs/contributors' + organization = 'uPortal Developers' + organizationUrl = 'https://github.com/Jasig/uPortal/graphs/contributors' } } } } } } + +java { + withJavadocJar() + withSourcesJar() +} \ No newline at end of file diff --git a/notification-portlet-webapp/build.gradle b/notification-portlet-webapp/build.gradle index 568570b6..e5d210f9 100644 --- a/notification-portlet-webapp/build.gradle +++ b/notification-portlet-webapp/build.gradle @@ -1,6 +1,6 @@ buildscript { ext { - springBootVersion = '1.5.22.RELEASE' + springBootVersion = '2.7.18' } repositories { mavenCentral() @@ -12,71 +12,83 @@ buildscript { plugins { id 'com.github.node-gradle.node' version '7.1.0' + id 'war' + id 'eclipse-wtp' + id 'org.springframework.boot' version '2.7.18' + id 'io.spring.dependency-management' version '1.0.15.RELEASE' } -apply plugin: 'java' -apply plugin: 'eclipse-wtp' -apply plugin: 'org.springframework.boot' -apply plugin: 'war' - -configurations { - providedRuntime +repositories { + mavenCentral() + maven { + url "https://repository.apache.org/content/repositories/releases/" + } + maven { + url "https://repo.spring.io/release" + } } + + dependencies { /* * Notification API */ - compile project(':notification-portlet-api') + implementation project(':notification-portlet-api') /* * Standard Dependencies */ - compile "com.google.guava:guava:${guavaVersion}" - compile "com.jayway.jsonpath:json-path:${jsonPathVersion}" - compile "net.minidev:json-smart:${jsonSmartVersion}" - compile "commons-codec:commons-codec:${commonsCodecVersion}" - compile "commons-dbcp:commons-dbcp:${commonsDbcpVersion}" - compile "io.springfox:springfox-swagger2:${springfoxVersion}" - compile "io.springfox:springfox-swagger-ui:${springfoxVersion}" - compile "javax.servlet:jstl:${jstlVersion}" - compile "joda-time:joda-time:${jodaTimeVersion}" - compile "net.sf.dozer:dozer:${dozerVersion}" - compile "net.sf.dozer:dozer-spring:${dozerVersion}" - compile("org.ehcache:ehcache:${ehcacheVersion}") - compile "org.apache.commons:commons-lang3:${commonsLang3Version}" - compile "org.apache.httpcomponents:httpclient:${httpcomponentsVersion}" - compile "org.aspectj:aspectjweaver:${aspectjVersion}" - compile "org.codehaus.janino:janino:${janinoVersion}" - compile "org.hibernate:hibernate-core:${hibernateVersion}" - compile("org.hibernate:hibernate-ehcache:${hibernateVersion}") { + implementation "com.google.guava:guava:${guavaVersion}" + implementation "com.jayway.jsonpath:json-path:${jsonPathVersion}" + implementation "net.minidev:json-smart:${jsonSmartVersion}" + implementation "commons-codec:commons-codec:${commonsCodecVersion}" + implementation "commons-dbcp:commons-dbcp:${commonsDbcpVersion}" +// implementation "io.springfox:springfox-swagger2:${springfoxVersion}" +// implementation "io.springfox:springfox-swagger-ui:${springfoxVersion}" + implementation 'org.springdoc:springdoc-openapi-ui:1.7.0' + implementation "javax.servlet:jstl:${jstlVersion}" + implementation "joda-time:joda-time:${jodaTimeVersion}" + implementation "net.sf.dozer:dozer:${dozerVersion}" + implementation "net.sf.dozer:dozer-spring:${dozerVersion}" + implementation("org.ehcache:ehcache:${ehcacheVersion}") + implementation "org.apache.commons:commons-lang3:${commonsLang3Version}" + implementation "org.apache.httpcomponents:httpclient:${httpcomponentsVersion}" + implementation "org.aspectj:aspectjweaver:${aspectjVersion}" + implementation "org.codehaus.janino:janino:${janinoVersion}" + implementation "org.hibernate:hibernate-core:${hibernateVersion}" + implementation("org.hibernate:hibernate-ehcache:${hibernateVersion}") { exclude group: 'net.sf.ehcache', module: 'ehcache-core' } - compile "org.hibernate:hibernate-entitymanager:${hibernateVersion}" - compile "org.jasig.resourceserver:resource-server-utils:${resourceServerVersion}" - compile("org.jasig.portal:uPortal-soffit-renderer:${uPortalVersion}") - compile "org.jasig.portal:uPortal-spring:${uPortalVersion}@jar" // Use @jar classifier to exclude transitive dependencies - compile "org.jasypt:jasypt-spring31:${jasyptVersion}" - compile "org.springframework:spring-jdbc:${springVersion}" - compile "org.springframework:spring-orm:${springVersion}" - compile "org.springframework:spring-tx:${springVersion}" - compile "org.springframework:spring-webmvc-portlet:${springVersion}" - compile "org.springframework.security.oauth:spring-security-oauth2:${springSecurityOAuth2Version}" - compile "com.rometools:rome:${romeVersion}" + implementation "org.hibernate:hibernate-entitymanager:${hibernateVersion}" + implementation "org.jasig.resourceserver:resource-server-utils:${resourceServerVersion}" + implementation("org.jasig.portal:uPortal-soffit-renderer:${uPortalVersion}") + implementation "org.jasig.portal:uPortal-spring:${uPortalVersion}@jar" // Use @jar classifier to exclude transitive dependencies + implementation "org.jasypt:jasypt-spring31:${jasyptVersion}" + implementation "org.springframework:spring-jdbc:${springVersion}" + implementation "org.springframework:spring-orm:${springVersion}" + implementation "org.springframework:spring-tx:${springVersion}" + implementation 'org.springframework:spring-webmvc-portlet:4.3.30.RELEASE' + implementation 'javax.portlet:portlet-api:2.0' + implementation 'org.apache.portals.pluto:pluto-taglib:3.1.0' + implementation 'org.apache.portals.pluto:pluto-container:3.1.0' + implementation 'org.apache.portals.pluto:pluto-portal-driver-impl:3.1.0' + implementation "org.springframework.security.oauth:spring-security-oauth2:${springSecurityOAuth2Version}" + implementation "com.rometools:rome:${romeVersion}" compileOnly "org.projectlombok:lombok:${lombokVersion}" annotationProcessor "org.projectlombok:lombok:${lombokVersion}" - compile "javax.annotation:javax.annotation-api:${annotationApiVersion}" - compile "javax.xml.bind:jaxb-api:${jaxbApiVersion}" + implementation "javax.annotation:javax.annotation-api:${annotationApiVersion}" + implementation "javax.xml.bind:jaxb-api:${jaxbApiVersion}" /* * Spring Boot */ - compile('org.springframework.boot:spring-boot-starter-cache') - compile('org.springframework.boot:spring-boot-starter-security') - compile('org.springframework.boot:spring-boot-starter-web') - providedRuntime('org.springframework.boot:spring-boot-starter-tomcat') - testCompile('org.springframework.boot:spring-boot-starter-test') + implementation('org.springframework.boot:spring-boot-starter-cache') + implementation('org.springframework.boot:spring-boot-starter-security') + implementation('org.springframework.boot:spring-boot-starter-web') + compileOnly('org.springframework.boot:spring-boot-starter-tomcat') + testImplementation('org.springframework.boot:spring-boot-starter-test') /* * Portlet API @@ -85,7 +97,7 @@ dependencies { * (but used) when the project is run inside Tomcat. */ compileOnly "${portletApiDependency}" - providedRuntime "${portletApiDependency}" + compileOnly "${portletApiDependency}" /* * JDBC Driver JAR(s) @@ -107,15 +119,21 @@ node { * This task produces a .jar archive from this module, which is in addition to the primary .war * archive. Adopters who with to extend the project may need this additional archive. */ -task classesJar(type: Jar) { +tasks.register('classesJar', Jar) { from sourceSets.main.output - classifier 'jar' + archiveClassifier = 'jar' } artifacts { archives classesJar } +bootWar { + enabled = false +} + war { + archiveClassifier = null + enabled = true from("${buildDir}/css") { into('css') } @@ -124,7 +142,8 @@ war { } } -task createCssAndJsOutputDirs(dependsOn: 'npm_ci') { +tasks.register('createCssAndJsOutputDirs') { + dependsOn 'npm_ci' doLast { mkdir "${buildDir}/css" mkdir "${buildDir}/scripts" @@ -140,32 +159,33 @@ war.dependsOn 'npm_run_minify-css' project.tasks.getByName('npm_run_compile-js').dependsOn createCssAndJsOutputDirs war.dependsOn 'npm_run_minify-js' -uploadArchives{ - repositories { - mavenDeployer { - pom.project { - name 'notification-portlet-webapp' - packaging 'war' - // optionally artifactId can be defined here - description 'SR-286 (Portlet 2.0) portlet to display important notices from campus systems' - url 'https://github.com/Jasig/NotificationPortlet' +publishing { + publications { + web(MavenPublication) { + from components.web + + pom { + name = 'notification-portlet-webapp' + packaging = 'war' + description = 'SR-286 (Portlet 2.0) portlet to display important notices from campus systems' + url = 'https://github.com/Jasig/NotificationPortlet' scm { - connection 'scm:git@github.com:Jasig/NotificationPortlet.git' - url 'https://github.com/Jasig/NotificationPortlet' + connection = 'scm:git@github.com:Jasig/NotificationPortlet.git' + url = 'https://github.com/Jasig/NotificationPortlet' } licenses { license { - name 'The Apache License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' } } developers { developer { - organization 'uPortal Developers' - organizationUrl 'https://github.com/Jasig/uPortal/graphs/contributors' + organization = 'uPortal Developers' + organizationUrl = 'https://github.com/Jasig/uPortal/graphs/contributors' } } } diff --git a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/NotificationApplication.java b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/NotificationApplication.java index b3854297..1f7b2911 100644 --- a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/NotificationApplication.java +++ b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/NotificationApplication.java @@ -20,9 +20,14 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.ImportResource; -@SpringBootApplication +@SpringBootApplication(exclude = { + HibernateJpaAutoConfiguration.class, + DataSourceAutoConfiguration.class +}) @ImportResource({"classpath:/context/*.xml","classpath:/properties/contextOverrides/*.xml"}) // Legacy, XML-based beans public class NotificationApplication { diff --git a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/ServletInitializer.java b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/ServletInitializer.java index b694aa87..28610e6f 100644 --- a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/ServletInitializer.java +++ b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/ServletInitializer.java @@ -19,7 +19,7 @@ package org.jasig.portlet.notice; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; public class ServletInitializer extends SpringBootServletInitializer { diff --git a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/SwaggerConfiguration.java b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/SwaggerConfiguration.java deleted file mode 100644 index 1d1929ef..00000000 --- a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/SwaggerConfiguration.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo licenses this file to you 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 the following location: - * - * 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.jasig.portlet.notice; - -import io.swagger.models.auth.In; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.service.ApiKey; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.SecurityReference; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -import java.util.Collections; - -/** - * Configuration for Swagger API documentation and HTML client. - */ -@Configuration -@EnableSwagger2 -public class SwaggerConfiguration { - - /** - * This string is used to link the Swagger ApiKey to the SecurityReference. - */ - private static final String API_KEY_NAME = "api_key"; - - @Bean - public Docket docket() { - return new Docket(DocumentationType.SWAGGER_2) - .securitySchemes(Collections.singletonList(apiKey())) - .securityContexts(Collections.singletonList(securityContext())); - } - - private ApiKey apiKey() { - return new ApiKey(API_KEY_NAME, HttpHeaders.AUTHORIZATION, In.HEADER.name()); - } - - private SecurityContext securityContext() { - return SecurityContext.builder() - .securityReferences(Collections.singletonList(securityReference())) - .forPaths(PathSelectors.regex("/api.*")) - .build(); - } - - private SecurityReference securityReference() { - final AuthorizationScope authorizationScope = - new AuthorizationScope("global", "Access REST APIs"); - return new SecurityReference(API_KEY_NAME, new AuthorizationScope[] { authorizationScope }); - } - -} diff --git a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/action/read/ReadNotificationServiceDecorator.java b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/action/read/ReadNotificationServiceDecorator.java index aabf4a1b..edfd0d43 100644 --- a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/action/read/ReadNotificationServiceDecorator.java +++ b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/action/read/ReadNotificationServiceDecorator.java @@ -93,7 +93,7 @@ public NotificationResponse fetch(PortletRequest req) { NotificationAttribute readAttribute = new NotificationAttribute(); readAttribute.setName(READ_ATTRIBUTE_NAME); - readAttribute.setValues(new ArrayList<>(Arrays.asList((new Boolean(true)).toString()))); + readAttribute.setValues(new ArrayList<>(List.of(Boolean.toString(true)))); // Add and implement the read behavior with our copy for (NotificationCategory category : rslt.getCategories()) { diff --git a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/controller/NotificationLifecycleController.java b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/controller/NotificationLifecycleController.java index fa8712b1..be29b668 100644 --- a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/controller/NotificationLifecycleController.java +++ b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/controller/NotificationLifecycleController.java @@ -27,12 +27,7 @@ import java.util.Set; import javax.annotation.Resource; -import javax.portlet.ActionRequest; -import javax.portlet.ActionResponse; -import javax.portlet.EventRequest; -import javax.portlet.EventResponse; -import javax.portlet.PortletPreferences; -import javax.portlet.ResourceRequest; +import javax.portlet.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -50,15 +45,20 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.portlet.ModelAndView; + import org.springframework.web.portlet.bind.annotation.ActionMapping; import org.springframework.web.portlet.bind.annotation.EventMapping; + +import org.springframework.stereotype.Controller; +import org.springframework.web.servlet.ModelAndView; +import javax.portlet.ResourceRequest; import org.springframework.web.portlet.bind.annotation.ResourceMapping; /** * Gathering of notifications requires action and sometimes event phases. This * controller serves that purpose. */ +@Controller @RequestMapping("VIEW") public class NotificationLifecycleController { @@ -93,7 +93,7 @@ public class NotificationLifecycleController { private INotificationService notificationService; @ResourceMapping("GET-NOTIFICATIONS-UNCATEGORIZED") - public ModelAndView getNotificationsUncategorized(final ResourceRequest req, final @RequestParam(value="refresh", required=false) String doRefresh) throws IOException { + public ModelAndView getNotificationsUncategorized(final ResourceRequest req, final @RequestParam(value="refresh", required=false) String doRefresh) throws IOException, PortletException { // RequestParam("key") String key, HttpServletRequest request, ModelMap model log.debug("Invoking getNotifications for user: " + usernameFinder.findUsername(req)); diff --git a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/security/SecurityConfiguration.java b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/security/SecurityConfiguration.java index 214bda87..659559a0 100644 --- a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/security/SecurityConfiguration.java +++ b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/security/SecurityConfiguration.java @@ -21,8 +21,6 @@ import org.apereo.portal.soffit.security.SoffitApiAuthenticationManager; import org.apereo.portal.soffit.security.SoffitApiPreAuthenticatedProcessingFilter; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.support.ErrorPageFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; @@ -121,23 +119,6 @@ public AuthenticationManager authenticationManager() { return new SoffitApiAuthenticationManager(); } - @Bean - public ErrorPageFilter errorPageFilter() { - return new ErrorPageFilter(); - } - - @Bean - public FilterRegistrationBean disableSpringBootErrorFilter() { - /* - * The ErrorPageFilter (Spring) makes extra calls to HttpServletResponse.flushBuffer(), - * and this behavior produces many warnings in the portal logs during portlet requests. - */ - FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); - filterRegistrationBean.setFilter(errorPageFilter()); - filterRegistrationBean.setEnabled(false); - return filterRegistrationBean; - } - @Bean("soffitSignatureKey") public String signatureKey() { return signatureKey; diff --git a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/service/jpa/MappingConfiguration.java b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/service/jpa/MappingConfiguration.java index 764a101b..2aeed6dc 100644 --- a/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/service/jpa/MappingConfiguration.java +++ b/notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/service/jpa/MappingConfiguration.java @@ -38,9 +38,11 @@ public class MappingConfiguration { @Autowired private ApplicationContext applicationContext; - @Bean("addresseePostProcessor") + @Autowired + private AddresseePostProcessor addresseePostProcessor; + public AddresseePostProcessor getAddresseePostProcessor() { - return new AddresseePostProcessor(); + return this.addresseePostProcessor; } @Bean diff --git a/notification-portlet-webapp/src/main/resources/application.properties b/notification-portlet-webapp/src/main/resources/application.properties index 244e5397..ed6707a6 100644 --- a/notification-portlet-webapp/src/main/resources/application.properties +++ b/notification-portlet-webapp/src/main/resources/application.properties @@ -29,3 +29,6 @@ # will be overridden by a Tomcat-provided system property.. # catalina.home=build + +spring.main.web-application-type=servlet +spring.jta.enabled=false \ No newline at end of file diff --git a/notification-portlet-webapp/src/test/java/org/jasig/portlet/notice/NotificationApplicationTests.java b/notification-portlet-webapp/src/test/java/org/jasig/portlet/notice/NotificationApplicationTests.java index f18d641c..6dc34c4b 100644 --- a/notification-portlet-webapp/src/test/java/org/jasig/portlet/notice/NotificationApplicationTests.java +++ b/notification-portlet-webapp/src/test/java/org/jasig/portlet/notice/NotificationApplicationTests.java @@ -21,14 +21,18 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest +@SpringBootTest(properties = {"spring.main.allow-bean-definition-overriding=true"}) public class NotificationApplicationTests { + @Configuration + static class TestConfig extends NotificationTestConfig { + } + @Test public void contextLoads() { } - -} +} \ No newline at end of file diff --git a/notification-portlet-webapp/src/test/java/org/jasig/portlet/notice/NotificationTestConfig.java b/notification-portlet-webapp/src/test/java/org/jasig/portlet/notice/NotificationTestConfig.java new file mode 100644 index 00000000..fc803092 --- /dev/null +++ b/notification-portlet-webapp/src/test/java/org/jasig/portlet/notice/NotificationTestConfig.java @@ -0,0 +1,124 @@ +package org.jasig.portlet.notice; + +import net.sf.ehcache.Cache; +import org.jasig.portlet.notice.action.favorite.FavoriteNotificationServiceDecorator; +import org.jasig.portlet.notice.action.hide.HideNotificationServiceDecorator; +import org.jasig.portlet.notice.action.read.ReadNotificationServiceDecorator; +import org.jasig.portlet.notice.controller.NotificationLifecycleController; +import org.jasig.portlet.notice.service.CacheNotificationService; +import org.jasig.portlet.notice.service.classloader.ClassLoaderResourceNotificationService; +import org.jasig.portlet.notice.service.filter.FilteringNotificationServiceDecorator; +import org.jasig.portlet.notice.service.rome.RomeNotificationService; +import org.jasig.portlet.notice.util.NotificationResponseFlattener; +import org.jasig.portlet.notice.util.UsernameFinder; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ReloadableResourceBundleMessageSource; + +import javax.portlet.PortletRequest; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +@Configuration +public class NotificationTestConfig { + @Bean + public UsernameFinder usernameFinder() { + UsernameFinder finder = new UsernameFinder(); + return finder; + } + + @Bean + public NotificationResponseFlattener notificationResponseFlattener() { + return new NotificationResponseFlattener(); + } + + @Bean + public NotificationLifecycleController notificationLifecycleController() { + return new NotificationLifecycleController(); + } + + @Bean("rootNotificationService") + public INotificationService rootNotificationService() { + HideNotificationServiceDecorator hideDecorator = new HideNotificationServiceDecorator(); + hideDecorator.setEnclosedNotificationService(readNotificationService()); + return hideDecorator; + } + + @Bean + public INotificationService readNotificationService() { + ReadNotificationServiceDecorator readDecorator = new ReadNotificationServiceDecorator(); + readDecorator.setEnclosedNotificationService(favoriteNotificationService()); + return readDecorator; + } + + @Bean + public INotificationService favoriteNotificationService() { + FavoriteNotificationServiceDecorator favoriteDecorator = new FavoriteNotificationServiceDecorator(); + favoriteDecorator.setEnclosedNotificationService(cacheNotificationService()); + return favoriteDecorator; + } + + @Bean + public CacheNotificationService cacheNotificationService() { + CacheNotificationService service = new CacheNotificationService(); + service.setName("notificationCacheNotificationService"); + + List embeddedServices = new ArrayList<>(); + + FilteringNotificationServiceDecorator classLoaderDecorator = new FilteringNotificationServiceDecorator(); + classLoaderDecorator.setEnclosedNotificationService(classLoaderResourceNotificationService()); + embeddedServices.add(classLoaderDecorator); + + FilteringNotificationServiceDecorator romeDecorator = new FilteringNotificationServiceDecorator(); + romeDecorator.setEnclosedNotificationService(romeNotificationService()); + embeddedServices.add(romeDecorator); + + service.setEmbeddedServices(embeddedServices); + return service; + } + + @Bean + public ClassLoaderResourceNotificationService classLoaderResourceNotificationService() { + ClassLoaderResourceNotificationService service = new ClassLoaderResourceNotificationService(); + service.setName("classLoaderResourceNotificationService"); + return service; + } + + @Bean + public RomeNotificationService romeNotificationService() { + RomeNotificationService service = new RomeNotificationService(); + service.setName("romeNotificationService"); + return service; + } + + @Bean("ClassLoaderResourceNotificationService.responseCache") + public Cache classLoaderResourceNotificationServiceCache() { + return new Cache("ClassLoaderResourceNotificationService.responseCache", + 10000, false, false, 300, 300); + } + + @Bean("RomeNotificationService.feedCache") + public Cache romeFeedCache() { + return new Cache("RomeNotificationService.feedCache", + 10000, false, false, 300, 300); + } + + @Bean("notificationResponseCache") + public Cache notificationResponseCache() { + return new Cache("notificationResponseCache", + 10000, false, false, 300, 300); + } + + @Bean + public MessageSource messageSource() { + ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + messageSource.setBasename("classpath:messages"); + messageSource.setDefaultEncoding("UTF-8"); + messageSource.setCommonMessages(new Properties() {{ + put("notice.date.format", "MM/dd/yyyy HH:mm:ss"); + }}); + return messageSource; + } +}