From fce64305d983ea35489ae8c3486bed7d690accf0 Mon Sep 17 00:00:00 2001 From: Mark Wareham Date: Thu, 7 Feb 2019 11:01:14 +0000 Subject: [PATCH 001/108] QA-3 Sonar PR analysis --- Jenkinsfile | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ce9625ff46f..c7b9c30786b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -27,11 +27,22 @@ pipeline { stage('Build') { steps { echo '*#*#*#*#*#*#*#*#*#*#*#*# Building SRC *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#' - sh """mvn -B -V -ff -e clean install -PQuickBuild \ - -Djavax.net.ssl.trustStore=${env.JAVA_HOME}/jre/lib/security/cacerts \ - -Djavax.xml.accessExternalSchema=all -Dbuild.number=${payaraBuildNumber} \ - -Dsurefire.rerunFailingTestsCount=2""" - echo '*#*#*#*#*#*#*#*#*#*#*#*# Built SRC *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#' + withCredentials([string(credentialsId: 'jenkins-held-sonarcloud-token-secret', variable: 'sonarToken')]) { + sh """mvn -B -V -ff -e clean install -PQuickBuild \ + -Djavax.net.ssl.trustStore=${env.JAVA_HOME}/jre/lib/security/cacerts \ + -Djavax.xml.accessExternalSchema=all -Dbuild.number=${payaraBuildNumber} \ + -Dsurefire.rerunFailingTestsCount=2 \ + -Dsonar.pullrequest.base=${env.ghprbTargetBranch} \ + -Dsonar.pullrequest.branch=${env.ghprbPullAuthorLogin}/${env.ghprbSourceBranch} \ + -Dsonar.pullrequest.key=${env.ghprbPullId} \ + -Dsonar.pullrequest.provider=GitHub \ + -Dsonar.pullrequest.github.repository=payara/payara \ + -Dsonar.organization=payara \ + -Dsonar.host.url=https://sonarcloud.io \ + -Dsonar.login=${sonarToken} \ + sonar:sonar""" + } + echo '*#*#*#*#*#*#*#*#*#*#*#*# Built SRC *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#' } post{ success{ From 47ed1cdb56592bc7e3f84fd1bf6626362c3cb93f Mon Sep 17 00:00:00 2001 From: Mark Wareham Date: Fri, 8 Feb 2019 11:25:33 +0000 Subject: [PATCH 002/108] QA-3 Sonar PR analysis --- Jenkinsfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Jenkinsfile b/Jenkinsfile index c7b9c30786b..0624e2ab461 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -27,6 +27,7 @@ pipeline { stage('Build') { steps { echo '*#*#*#*#*#*#*#*#*#*#*#*# Building SRC *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#' + env.GIT_COMMIT = sh 'git rev-parse HEAD' withCredentials([string(credentialsId: 'jenkins-held-sonarcloud-token-secret', variable: 'sonarToken')]) { sh """mvn -B -V -ff -e clean install -PQuickBuild \ -Djavax.net.ssl.trustStore=${env.JAVA_HOME}/jre/lib/security/cacerts \ From 40892b9ebf085d2ba843582753007fd367dbdf6a Mon Sep 17 00:00:00 2001 From: Mark Wareham Date: Tue, 12 Feb 2019 14:48:07 +0000 Subject: [PATCH 003/108] QA-3 sonar PR analysis --- Jenkinsfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0624e2ab461..f10bbd2139d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -27,7 +27,9 @@ pipeline { stage('Build') { steps { echo '*#*#*#*#*#*#*#*#*#*#*#*# Building SRC *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#' - env.GIT_COMMIT = sh 'git rev-parse HEAD' + script{ + env.GIT_COMMIT = sh 'git rev-parse HEAD' + } withCredentials([string(credentialsId: 'jenkins-held-sonarcloud-token-secret', variable: 'sonarToken')]) { sh """mvn -B -V -ff -e clean install -PQuickBuild \ -Djavax.net.ssl.trustStore=${env.JAVA_HOME}/jre/lib/security/cacerts \ From 9e9929f5ad00bbbf6c65425950c41a088172838b Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 26 Feb 2019 17:05:35 +0100 Subject: [PATCH 004/108] QA-186 fixes for issues found by tests for new health check as-admin commands --- .../nucleus/healthcheck/HealthCheckService.java | 11 ++++++++--- .../admin/SetHealthCheckConfiguration.java | 6 +++--- .../admin/SetHealthCheckServiceConfiguration.java | 8 +++----- .../SetHealthCheckServiceNotifierConfiguration.java | 4 ++-- .../domain/NotifierExecutionOptionsFactoryStore.java | 3 ++- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/HealthCheckService.java b/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/HealthCheckService.java index b0f81bd7e50..48e3b066609 100644 --- a/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/HealthCheckService.java +++ b/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/HealthCheckService.java @@ -46,6 +46,7 @@ import fish.payara.nucleus.notification.configuration.Notifier; import fish.payara.nucleus.notification.configuration.NotifierConfigurationType; import fish.payara.nucleus.notification.domain.NotifierExecutionOptions; +import fish.payara.nucleus.notification.domain.NotifierExecutionOptionsFactory; import fish.payara.nucleus.notification.domain.NotifierExecutionOptionsFactoryStore; import fish.payara.nucleus.notification.log.LogNotifier; import fish.payara.nucleus.notification.log.LogNotifierExecutionOptions; @@ -208,13 +209,16 @@ public void bootstrapHealthCheck() { /** * Starts all notifiers that have been enable with the healthcheck service. */ - public void bootstrapNotifierList() { + public synchronized void bootstrapNotifierList() { notifierExecutionOptionsList = new ArrayList<>(); if (configuration.getNotifierList() != null) { for (Notifier notifier : configuration.getNotifierList()) { ConfigView view = ConfigSupport.getImpl(notifier); NotifierConfigurationType annotation = view.getProxyType().getAnnotation(NotifierConfigurationType.class); - notifierExecutionOptionsList.add(executionOptionsFactoryStore.get(annotation.type()).build(notifier)); + NotifierExecutionOptionsFactory factory = executionOptionsFactoryStore.get(annotation.type()); + if (factory != null) { + notifierExecutionOptionsList.add(factory.build(notifier)); + } } } if (notifierExecutionOptionsList.isEmpty()) { @@ -300,7 +304,8 @@ public void shutdownHealthCheck() { } public BaseHealthCheck getCheck(String serviceName) { - return registeredTasks.get(serviceName).getCheck(); + HealthCheckTask task = registeredTasks.get(serviceName); + return task == null ? null : task.getCheck(); } /** diff --git a/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckConfiguration.java b/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckConfiguration.java index afd4ec8a800..a64bf8be0db 100644 --- a/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckConfiguration.java +++ b/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckConfiguration.java @@ -120,7 +120,7 @@ public class SetHealthCheckConfiguration implements AdminCommand { private String target; @Param(name = "enabled") - private boolean enabled; + private Boolean enabled; @Param(name = "historical-trace-enabled", optional = true) private Boolean historicalTraceEnabled; @@ -157,7 +157,7 @@ private void updateConfig(HealthCheckServiceConfiguration config, AdminCommandCo final ActionReport report = initActionReport(context); try { ConfigSupport.apply(configProxy -> { - configProxy.enabled(String.valueOf(enabled)); + configProxy.enabled(enabled.toString()); configProxy.setHistoricalTraceStoreSize(String.valueOf(historicalTraceStoreSize)); if (historicalTraceEnabled != null) { configProxy.setHistoricalTraceEnabled(historicalTraceEnabled.toString()); @@ -183,7 +183,7 @@ private void updateLogNotifier(AdminCommandContext context) { ParameterMap params = new ParameterMap(); params.add("target", target); params.add("dynamic", String.valueOf(dynamic)); - params.add("enabled", String.valueOf(enabled)); + params.add("enabled", enabled.toString()); params.add("notifier", NotifierType.LOG.name().toLowerCase()); // noisy will default to the notifier's config when not set so we do not set it as this is what we want inv.parameters(params); diff --git a/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckServiceConfiguration.java b/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckServiceConfiguration.java index d9d116e81f9..43b1535279a 100644 --- a/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckServiceConfiguration.java +++ b/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckServiceConfiguration.java @@ -143,7 +143,7 @@ public class SetHealthCheckServiceConfiguration implements AdminCommand { // general properties params: @Param(name = "enabled", optional = false) - private boolean enabled; + private Boolean enabled; @Param(name = "time", optional = true) @Min(value = 1, message = "Time period must be 1 or more") @@ -293,9 +293,7 @@ private void updateSe private void configureDynamically( BaseHealthCheck service, C config) { - if (service.getOptions() == null) { - service.setOptions(service.constructOptions(config)); - } + service.setOptions(service.constructOptions(config)); healthCheckService.registerCheck(config.getName(), service); healthCheckService.reboot(); if (service instanceof BaseThresholdHealthCheck) { @@ -326,7 +324,7 @@ private void configureDynamically(BaseThresholdHealthCheck service) { } private Checker updateProperties(Checker config, Class type) throws PropertyVetoException { - updateProperty(config, "enabled", config.getEnabled(), String.valueOf(enabled), Checker::setEnabled); + updateProperty(config, "enabled", config.getEnabled(), enabled.toString(), Checker::setEnabled); updateProperty(config, "time", config.getTime(), time, Checker::setTime); updateProperty(config, "time-unit", config.getUnit(), timeUnit, Checker::setUnit); if (HoggingThreadsChecker.class.isAssignableFrom(type)) { diff --git a/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckServiceNotifierConfiguration.java b/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckServiceNotifierConfiguration.java index 6645321f0cd..ee70a23babb 100644 --- a/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckServiceNotifierConfiguration.java +++ b/nucleus/payara-modules/healthcheck-core/src/main/java/fish/payara/nucleus/healthcheck/admin/SetHealthCheckServiceNotifierConfiguration.java @@ -127,7 +127,7 @@ public class SetHealthCheckServiceNotifierConfiguration implements AdminCommand private Config targetConfig; @Param(name = "enabled") - private boolean enabled; + private Boolean enabled; @Param(name = "noisy", optional = true) private Boolean noisy; @@ -186,7 +186,7 @@ public void execute(AdminCommandContext context) { } private void applyValues(Notifier notifier) throws PropertyVetoException { - if (Boolean.parseBoolean(notifier.getEnabled()) != enabled) { + if (Boolean.parseBoolean(notifier.getEnabled()) != enabled.booleanValue()) { report.appendMessage(notifierName + ".enabled was " + notifier.getEnabled() + " set to " + enabled + "\n"); notifier.enabled(enabled); } diff --git a/nucleus/payara-modules/notification-core/src/main/java/fish/payara/nucleus/notification/domain/NotifierExecutionOptionsFactoryStore.java b/nucleus/payara-modules/notification-core/src/main/java/fish/payara/nucleus/notification/domain/NotifierExecutionOptionsFactoryStore.java index f7248a553dc..95ba16bef1f 100644 --- a/nucleus/payara-modules/notification-core/src/main/java/fish/payara/nucleus/notification/domain/NotifierExecutionOptionsFactoryStore.java +++ b/nucleus/payara-modules/notification-core/src/main/java/fish/payara/nucleus/notification/domain/NotifierExecutionOptionsFactoryStore.java @@ -47,6 +47,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * @author mertcaliskan @@ -56,7 +57,7 @@ public class NotifierExecutionOptionsFactoryStore { private Map execOptionsFactoryStore = - new HashMap(); + new ConcurrentHashMap(); public NotifierExecutionOptionsFactory get(NotifierType type) { return execOptionsFactoryStore.get(type); From c5fec4e560c84d85e5b9b6a5403b167d6acc5b51 Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Thu, 7 Mar 2019 16:30:40 +0000 Subject: [PATCH 005/108] updated poms from REST to HTTP --- appserver/ejb/ejb-rest-remoting/admin/pom.xml | 10 +++++----- appserver/ejb/ejb-rest-remoting/client/pom.xml | 12 ++++++------ appserver/ejb/ejb-rest-remoting/endpoint/pom.xml | 10 +++++----- appserver/ejb/ejb-rest-remoting/pom.xml | 10 +++++----- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/appserver/ejb/ejb-rest-remoting/admin/pom.xml b/appserver/ejb/ejb-rest-remoting/admin/pom.xml index 7be28e266ad..3d971033bc3 100644 --- a/appserver/ejb/ejb-rest-remoting/admin/pom.xml +++ b/appserver/ejb/ejb-rest-remoting/admin/pom.xml @@ -43,17 +43,17 @@ 4.0.0 - fish.payara.ejb.rest - ejb-rest-remoting + fish.payara.ejb.http + ejb-http-remoting 5.192-SNAPSHOT - ejb-rest-admin + ejb-http-admin glassfish-jar - EJB - Rest Admin + EJB - HTTP Admin - CLI (Asadmin) commands to configure the EJB REST endpoint. This contains commands to enable and disable the endpoint that invokes an EJB and + CLI (Asadmin) commands to configure the EJB HTTP endpoint. This contains commands to enable and disable the endpoint that invokes an EJB and to set the context root on which this endpoint is listening. diff --git a/appserver/ejb/ejb-rest-remoting/client/pom.xml b/appserver/ejb/ejb-rest-remoting/client/pom.xml index 5dd551ce718..e52190577b9 100644 --- a/appserver/ejb/ejb-rest-remoting/client/pom.xml +++ b/appserver/ejb/ejb-rest-remoting/client/pom.xml @@ -42,17 +42,17 @@ 4.0.0 - fish.payara.ejb.rest + fish.payara.ejb.http ejb-rest-remoting 5.192-SNAPSHOT - ejb-rest-client + ejb-http-client - EJB - REST Client + EJB - HTTP Client - Module providing support for the EJB Rest Client. This contains an InitialContext based lookup mechanism that uses REST calls back - to Payara to lookup EJB beans, as well as a proxy mechanism to invoke methods on an EJB, which will be sent via REST all well + Module providing support for the EJB HTTP Client. This contains an InitialContext based lookup mechanism that uses HTTP calls back + to Payara to lookup EJB beans, as well as a proxy mechanism to invoke methods on an EJB, which will be sent via HTTP all well to Payara. @@ -65,7 +65,7 @@ true - fish.payara.ejb.rest.client.*;version=${project.version} + fish.payara.ejb.http.client.*;version=${project.version} true diff --git a/appserver/ejb/ejb-rest-remoting/endpoint/pom.xml b/appserver/ejb/ejb-rest-remoting/endpoint/pom.xml index f94d80459c8..7aa4a287158 100644 --- a/appserver/ejb/ejb-rest-remoting/endpoint/pom.xml +++ b/appserver/ejb/ejb-rest-remoting/endpoint/pom.xml @@ -43,17 +43,17 @@ 4.0.0 - fish.payara.ejb.rest - ejb-rest-remoting + fish.payara.ejb.http + ejb-http-remoting 5.192-SNAPSHOT - ejb-rest-endpoint + ejb-http-endpoint war - EJB - REST Endpoint + EJB - HTTP Endpoint - This module contains the endpoint that services REST commands from the client (fish.payara.ejb.rest:ejb-rest-client) and looks EJBs up and invokes them. + This module contains the endpoint that services HTTP commands from the client (fish.payara.ejb.http:ejb-http-client) and looks EJBs up and invokes them. It contains a mini web application that is picked up by the domain template (org.glassfish.main.admin:nucleus-domain) which places it in the glassfish/domains/[domainname]/endpoints/ejb-invoker folder. diff --git a/appserver/ejb/ejb-rest-remoting/pom.xml b/appserver/ejb/ejb-rest-remoting/pom.xml index 90ac04b4730..7f8c10c3bca 100755 --- a/appserver/ejb/ejb-rest-remoting/pom.xml +++ b/appserver/ejb/ejb-rest-remoting/pom.xml @@ -46,16 +46,16 @@ 5.192-SNAPSHOT - fish.payara.ejb.rest - ejb-rest-remoting + fish.payara.ejb.http + ejb-http-remoting pom - EJB - REST + EJB - HTTP - This module is the parent module for the lightweight REST-based EJB remote system. It contains an admin + This module is the parent module for the lightweight HTTP-based EJB remote system. It contains an admin module that has CLI (AsAdmin) commands for configuring the server side. An endpoint module that implements - the endpoint which receives the REST calls from the client and invoked an EJB, and finally a client module + the endpoint which receives the HTTP calls from the client and invoked an EJB, and finally a client module which is used by the client to lookup and invoke EJB methods on a proxy. From 8de3bfdc856228bfc1ca14035e5701d90c31def6 Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Thu, 7 Mar 2019 16:31:59 +0000 Subject: [PATCH 006/108] Updated ejb folder name --- appserver/ejb/ejb-rest-remoting/admin/pom.xml | 77 ---- .../rest/admin/DisableEjbInvokerCommand.java | 128 ------ .../rest/admin/EnableEjbInvokerCommand.java | 129 ------ .../ejb/ejb-rest-remoting/client/pom.xml | 90 ---- .../ejb/rest/client/EjbRestProxyFactory.java | 86 ---- .../ejb/rest/client/EjbRestProxyHandler.java | 153 ------- .../ejb/rest/client/RemoteEJBContext.java | 387 ------------------ .../rest/client/RemoteEJBContextFactory.java | 85 ---- .../ejb/ejb-rest-remoting/endpoint/pom.xml | 91 ---- .../payara/ejb/invoke/InvokeEJBServlet.java | 215 ---------- appserver/ejb/ejb-rest-remoting/pom.xml | 68 --- 11 files changed, 1509 deletions(-) delete mode 100644 appserver/ejb/ejb-rest-remoting/admin/pom.xml delete mode 100644 appserver/ejb/ejb-rest-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java delete mode 100644 appserver/ejb/ejb-rest-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java delete mode 100644 appserver/ejb/ejb-rest-remoting/client/pom.xml delete mode 100644 appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java delete mode 100644 appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java delete mode 100644 appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java delete mode 100644 appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java delete mode 100644 appserver/ejb/ejb-rest-remoting/endpoint/pom.xml delete mode 100644 appserver/ejb/ejb-rest-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java delete mode 100755 appserver/ejb/ejb-rest-remoting/pom.xml diff --git a/appserver/ejb/ejb-rest-remoting/admin/pom.xml b/appserver/ejb/ejb-rest-remoting/admin/pom.xml deleted file mode 100644 index 3d971033bc3..00000000000 --- a/appserver/ejb/ejb-rest-remoting/admin/pom.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - 4.0.0 - - - fish.payara.ejb.http - ejb-http-remoting - 5.192-SNAPSHOT - - - ejb-http-admin - glassfish-jar - - EJB - HTTP Admin - - CLI (Asadmin) commands to configure the EJB HTTP endpoint. This contains commands to enable and disable the endpoint that invokes an EJB and - to set the context root on which this endpoint is listening. - - - - - org.glassfish.main.deployment - deployment-autodeploy - ${project.version} - - - org.glassfish.main.common - internal-api - ${project.version} - - - javax - javaee-api - ${javaee.api.version} - - - diff --git a/appserver/ejb/ejb-rest-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java b/appserver/ejb/ejb-rest-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java deleted file mode 100644 index 9d26352ab71..00000000000 --- a/appserver/ejb/ejb-rest-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can - * obtain a copy of the License at - * https://github.com/payara/Payara/blob/master/LICENSE.txt - * See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at glassfish/legal/LICENSE.txt. - * - * GPL Classpath Exception: - * The Payara Foundation designates this particular file as subject to the "Classpath" - * exception as provided by the Payara Foundation in the GPL Version 2 section of the License - * file that accompanied this code. - * - * Modifications: - * If applicable, add the following below the License Header, with the fields - * enclosed by brackets [] replaced by your own identifying information: - * "Portions Copyright [year] [name of copyright owner]" - * - * Contributor(s): - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ -package fish.payara.ejb.rest.admin; - -import static org.glassfish.config.support.CommandTarget.CLUSTER; -import static org.glassfish.config.support.CommandTarget.CLUSTERED_INSTANCE; -import static org.glassfish.config.support.CommandTarget.CONFIG; -import static org.glassfish.config.support.CommandTarget.DAS; -import static org.glassfish.config.support.CommandTarget.DEPLOYMENT_GROUP; -import static org.glassfish.config.support.CommandTarget.STANDALONE_INSTANCE; -import static org.glassfish.deployment.autodeploy.AutoDeployer.getNameFromFilePath; - -import java.nio.file.Path; - -import javax.inject.Inject; - -import com.sun.enterprise.config.serverbeans.Domain; -import org.glassfish.api.ActionReport; -import org.glassfish.api.Param; -import org.glassfish.api.admin.AdminCommand; -import org.glassfish.api.admin.AdminCommandContext; -import org.glassfish.api.admin.ExecuteOn; -import org.glassfish.api.admin.RuntimeType; -import org.glassfish.api.admin.ServerEnvironment; -import org.glassfish.config.support.TargetType; -import org.glassfish.deployment.autodeploy.AutoDeployer.AutodeploymentStatus; -import org.glassfish.deployment.autodeploy.AutoUndeploymentOperation; -import org.glassfish.hk2.api.PerLookup; -import org.glassfish.hk2.api.ServiceLocator; -import org.jvnet.hk2.annotations.Service; - -/** - * This command disables the EJB invoker endpoint. - * - *

- * This happens by undeploying the small application in /domains/[domain]/endpoints/ejb-invoker. - * Note that by default this application is not deployed. The default context root of this application is - * /ejb-invoker, but it may have been set to a different root by the {@link EnableEjbInvokerCommand} - * command. - * - * @author Arjan Tijms - * - */ -@Service(name = "disable-ejb-invoker") -@PerLookup -@ExecuteOn(RuntimeType.DAS) -@TargetType({ DAS, STANDALONE_INSTANCE, CLUSTER, CLUSTERED_INSTANCE, CONFIG, DEPLOYMENT_GROUP }) -public class DisableEjbInvokerCommand implements AdminCommand { - - private final String ENDPOINTS = "endpoints"; - private final String EJB_INVOKER = "ejb-invoker"; - - @Param(optional = true) - public String target; - - @Inject - private ServerEnvironment serverEnvironment; - - @Inject - private ServiceLocator serviceLocator; - - @Inject - private Domain domain; - - @Override - public void execute(AdminCommandContext context) { - - Path endPointsPath = serverEnvironment.getInstanceRoot().toPath().resolve(ENDPOINTS); - Path ejbInvokerPath = endPointsPath.resolve(EJB_INVOKER); - - AutoUndeploymentOperation autoUndeploymentOperation = AutoUndeploymentOperation.newInstance( - serviceLocator, - ejbInvokerPath.toFile(), - getNameFromFilePath(endPointsPath.toFile(), ejbInvokerPath.toFile()), - target); - - AutodeploymentStatus deploymentStatus = autoUndeploymentOperation.run(); - - ActionReport report = context.getActionReport(); - report.setActionExitCode(deploymentStatus.getExitCode()); - - if (deploymentStatus.getExitCode().equals(ActionReport.ExitCode.FAILURE)) { - if (domain.getApplications().getApplication("ejb-invoker") == null) { - report.appendMessage("\nEJB Invoker is not enabled on any target"); - } else { - report.appendMessage("\nFailed to disable Ejb Invoker - was it enabled on the specified target?"); - } - } - } - -} diff --git a/appserver/ejb/ejb-rest-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java b/appserver/ejb/ejb-rest-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java deleted file mode 100644 index 99c35c0bfa3..00000000000 --- a/appserver/ejb/ejb-rest-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can - * obtain a copy of the License at - * https://github.com/payara/Payara/blob/master/LICENSE.txt - * See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at glassfish/legal/LICENSE.txt. - * - * GPL Classpath Exception: - * The Payara Foundation designates this particular file as subject to the "Classpath" - * exception as provided by the Payara Foundation in the GPL Version 2 section of the License - * file that accompanied this code. - * - * Modifications: - * If applicable, add the following below the License Header, with the fields - * enclosed by brackets [] replaced by your own identifying information: - * "Portions Copyright [year] [name of copyright owner]" - * - * Contributor(s): - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ -package fish.payara.ejb.rest.admin; - -import static org.glassfish.config.support.CommandTarget.CLUSTER; -import static org.glassfish.config.support.CommandTarget.CLUSTERED_INSTANCE; -import static org.glassfish.config.support.CommandTarget.CONFIG; -import static org.glassfish.config.support.CommandTarget.DAS; -import static org.glassfish.config.support.CommandTarget.DEPLOYMENT_GROUP; -import static org.glassfish.config.support.CommandTarget.STANDALONE_INSTANCE; - -import javax.inject.Inject; - -import com.sun.enterprise.config.serverbeans.Domain; -import org.glassfish.api.ActionReport; -import org.glassfish.api.Param; -import org.glassfish.api.admin.AdminCommand; -import org.glassfish.api.admin.AdminCommandContext; -import org.glassfish.api.admin.ExecuteOn; -import org.glassfish.api.admin.RuntimeType; -import org.glassfish.api.admin.ServerEnvironment; -import org.glassfish.config.support.TargetType; -import org.glassfish.deployment.autodeploy.AutoDeployer.AutodeploymentStatus; -import org.glassfish.deployment.autodeploy.AutoDeploymentOperation; -import org.glassfish.hk2.api.PerLookup; -import org.glassfish.hk2.api.ServiceLocator; -import org.jvnet.hk2.annotations.Service; - -/** - * This command enables the EJB invoker endpoint and optionally allows it to set an - * alternative context root. - * - *

- * This happens by the deploying a small application in /domains/[domain]/endpoints/ejb-invoker - * which by default is not deployed. The default context root of this application is - * /ejb-invoker. - * - * @author Arjan Tijms - * - */ -@Service(name = "enable-ejb-invoker") -@PerLookup -@ExecuteOn(RuntimeType.DAS) -@TargetType({ DAS, STANDALONE_INSTANCE, CLUSTER, CLUSTERED_INSTANCE, CONFIG, DEPLOYMENT_GROUP }) -public class EnableEjbInvokerCommand implements AdminCommand { - - private final String ENDPOINT = "endpoints/ejb-invoker"; - - @Param(name = "contextRoot", primary = true, optional = true) - private String contextRoot; - - @Param(optional = true) - public String target; - - @Inject - private ServerEnvironment serverEnvironment; - - @Inject - private ServiceLocator serviceLocator; - - @Inject - private Domain domain; - - @Override - public void execute(AdminCommandContext context) { - AutoDeploymentOperation autoDeploymentOperation = AutoDeploymentOperation.newInstance( - serviceLocator, - serverEnvironment.getInstanceRoot().toPath().resolve(ENDPOINT).toFile(), - getDefaultVirtualServer(), - target, - contextRoot - ); - - if (domain.getApplications().getApplication("ejb-invoker") == null) { - AutodeploymentStatus deploymentStatus = autoDeploymentOperation.run(); - ActionReport report = context.getActionReport(); - report.setActionExitCode(deploymentStatus.getExitCode()); - } else { - ActionReport report = context.getActionReport(); - report.setActionExitCode(ActionReport.ExitCode.WARNING); - report.setMessage("EJB Invoker is already deployed on at least one target, please edit it as you would a " + - "normal application using the create-application-ref, delete-application-ref, " + - "or update-application-ref commands"); - } - } - - private String getDefaultVirtualServer() { - // XXX write this? - return null; - } - -} diff --git a/appserver/ejb/ejb-rest-remoting/client/pom.xml b/appserver/ejb/ejb-rest-remoting/client/pom.xml deleted file mode 100644 index e52190577b9..00000000000 --- a/appserver/ejb/ejb-rest-remoting/client/pom.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - - 4.0.0 - - - fish.payara.ejb.http - ejb-rest-remoting - 5.192-SNAPSHOT - - - ejb-http-client - - EJB - HTTP Client - - Module providing support for the EJB HTTP Client. This contains an InitialContext based lookup mechanism that uses HTTP calls back - to Payara to lookup EJB beans, as well as a proxy mechanism to invoke methods on an EJB, which will be sent via HTTP all well - to Payara. - - - - - - org.apache.felix - maven-bundle-plugin - true - true - - - fish.payara.ejb.http.client.*;version=${project.version} - - true - - - - - - - - org.glassfish.jersey.core - jersey-client - - - org.glassfish.jersey.core - jersey-common - - - javax.json - javax.json-api - - - diff --git a/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java b/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java deleted file mode 100644 index 58592bd0339..00000000000 --- a/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can - * obtain a copy of the License at - * https://github.com/payara/Payara/blob/master/LICENSE.txt - * See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at glassfish/legal/LICENSE.txt. - * - * GPL Classpath Exception: - * The Payara Foundation designates this particular file as subject to the "Classpath" - * exception as provided by the Payara Foundation in the GPL Version 2 section of the License - * file that accompanied this code. - * - * Modifications: - * If applicable, add the following below the License Header, with the fields - * enclosed by brackets [] replaced by your own identifying information: - * "Portions Copyright [year] [name of copyright owner]" - * - * Contributor(s): - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ -package fish.payara.ejb.rest.client; - -import static java.lang.reflect.Proxy.newProxyInstance; -import static java.security.AccessController.doPrivileged; -import static java.util.Collections.emptyList; -import static org.glassfish.jersey.internal.util.ReflectionHelper.getClassLoaderPA; - -import java.util.List; -import java.util.Map; - -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.Cookie; -import javax.ws.rs.core.MultivaluedHashMap; -import javax.ws.rs.core.MultivaluedMap; - -/** - * This class generates a type-safe proxy for a given remote EJB interface. - * - *

- * Calls on this proxy are handled by {@link EjbRestProxyHandler}. - * - * - * @author Arjan Tijms - * @since Payara 5.191 - * - */ -final class EjbRestProxyFactory { - - private static final MultivaluedMap EMPTY_MULTI_MAP = new MultivaluedHashMap<>(); - - public static C newProxy(Class remoteBusinessInterface, WebTarget target, String lookup, Map jndiOptions) { - return newProxy(remoteBusinessInterface, target, EMPTY_MULTI_MAP, emptyList(), lookup, jndiOptions); - } - - @SuppressWarnings("unchecked") - public static C newProxy(Class remoteBusinessInterface, WebTarget target, MultivaluedMap headers, List cookies, String lookup, Map jndiOptions) { - return (C) - newProxyInstance(doPrivileged(getClassLoaderPA(remoteBusinessInterface)), - new Class[] { remoteBusinessInterface }, - new EjbRestProxyHandler(addPathFromClass(remoteBusinessInterface, target), headers, cookies, lookup, jndiOptions)); - } - - private static WebTarget addPathFromClass(Class clazz, WebTarget target) { - return target.path(clazz.getSimpleName()); - } - -} diff --git a/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java b/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java deleted file mode 100644 index 23c5f67d719..00000000000 --- a/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java +++ /dev/null @@ -1,153 +0,0 @@ -package fish.payara.ejb.rest.client; - -import static javax.naming.Context.SECURITY_CREDENTIALS; -import static javax.naming.Context.SECURITY_PRINCIPAL; -import static javax.ws.rs.HttpMethod.POST; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; -import java.util.Base64; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.Future; - -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.Cookie; -import javax.ws.rs.core.GenericType; -import javax.ws.rs.core.MultivaluedHashMap; -import javax.ws.rs.core.MultivaluedMap; - -/** - * This class handles invocations (method calls) on a proxy generated by {@link EjbRestProxyFactory}. - * - *

- * This proxy uses REST calls to an endpoint in a given remote Payara server. - * - * @author Arjan Tijms - * @since Payara 5.191 - * - */ -class EjbRestProxyHandler implements InvocationHandler { - - private final WebTarget target; - private final MultivaluedMap headers; - private final List cookies; - private final String lookup; - private final Map jndiOptions; - - EjbRestProxyHandler(WebTarget target, MultivaluedMap headers, List cookies, String lookup, Map jndiOptions) { - this.target = target; - this.headers = headers; - this.cookies = cookies; - this.lookup = lookup; - this.jndiOptions = jndiOptions; - } - - @Override - public Object invoke(Object proxy, Method method, Object[] argValues) throws Throwable { - - // Check for methods we should not proxy first - - if (argValues == null && method.getName().equals("toString")) { - return toString(); - } - - if (argValues == null && method.getName().equals("hashCode")) { - // unique instance in the JVM, and no need to override - return hashCode(); - } - - if (argValues != null && argValues.length == 1 && method.getName().equals("equals")) { - // unique instance in the JVM, and no need to override - return equals(argValues[0]); - } - - // Valid method, do invoke it remotely - return doRemoteInvoke(proxy, method, argValues); - } - - public Object doRemoteInvoke(Object proxy, Method method, Object[] argValues) throws Throwable { - // HTTP method name; we're always using POST to invoke remote EJBs - String httpMethod = POST; - - // The bare payload being sent - Map payload = new HashMap<>(); - payload.put("lookup", lookup); - payload.put("method", method.getName()); - payload.put("argTypes", method.getParameterTypes()); - payload.put("argValues", argValues == null? new Object[0] : argValues); - - if (jndiOptions.containsKey(SECURITY_PRINCIPAL)) { - payload.put(SECURITY_PRINCIPAL, base64Encode(jndiOptions.get(SECURITY_PRINCIPAL))); - } - - if (jndiOptions.containsKey(SECURITY_CREDENTIALS)) { - payload.put(SECURITY_CREDENTIALS, base64Encode(jndiOptions.get(SECURITY_CREDENTIALS))); - } - - // Payload wrapped as entity so it'll be encoded in JSON - Entity entity = Entity.entity(payload, APPLICATION_JSON); - - // Response type - Class responseType = method.getReturnType(); - GenericType responseGenericType = new GenericType<>(method.getGenericReturnType()); - - // Create a new UriBuilder appending the name from the method - WebTarget newTarget = addPathFromMethod(method, target); - - // Start request - Invocation.Builder builder = newTarget.request(); - - // Set optional headers and cookies - builder.headers(new MultivaluedHashMap(this.headers)); - for (Cookie cookie : new LinkedList<>(this.cookies)) { - builder = builder.cookie(cookie); - } - - // Call remote server - - if (responseType.isAssignableFrom(CompletionStage.class)) { - - // Reactive call - the actual response type is T from CompletionStage - return builder.rx().method(httpMethod, entity, getResponseParameterizedType(method, responseGenericType)); - } else if (responseType.isAssignableFrom(Future.class)) { - - // Asynchronous call - the actual response type is T from Future - return builder.async().method(httpMethod, entity, getResponseParameterizedType(method, responseGenericType)); - } - - // Synchronous call - return builder.method(httpMethod, entity, responseGenericType); - } - - private GenericType getResponseParameterizedType(Method method, GenericType responseGenericType) { - if (method.getGenericReturnType() instanceof ParameterizedType) { - ParameterizedType parameterizedType = (ParameterizedType) method.getGenericReturnType(); - - return new GenericType<>(parameterizedType.getActualTypeArguments()[0]); - } - - return responseGenericType; - } - - private static String base64Encode(Object input) { - return Base64.getEncoder().encodeToString(input.toString().getBytes()); - } - - private static WebTarget addPathFromMethod(Method method, WebTarget target) { - return target.path(method.getName()); - } - - @Override - public String toString() { - return target.toString(); - } - -} diff --git a/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java b/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java deleted file mode 100644 index f961a081252..00000000000 --- a/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can - * obtain a copy of the License at - * https://github.com/payara/Payara/blob/master/LICENSE.txt - * See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at glassfish/legal/LICENSE.txt. - * - * GPL Classpath Exception: - * The Payara Foundation designates this particular file as subject to the "Classpath" - * exception as provided by the Payara Foundation in the GPL Version 2 section of the License - * file that accompanied this code. - * - * Modifications: - * If applicable, add the following below the License Header, with the fields - * enclosed by brackets [] replaced by your own identifying information: - * "Portions Copyright [year] [name of copyright owner]" - * - * Contributor(s): - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ -package fish.payara.ejb.rest.client; - -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_CONNECT_TIMEOUT; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_EXECUTOR_SERVICE; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_HOSTNAME_VERIFIER; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_KEY_STORE; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_READ_TIMEOUT; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_SSL_CONTEXT; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_TRUST_STORE; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_WITH_CONFIG; -import static java.util.concurrent.TimeUnit.MICROSECONDS; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; - -import java.net.URI; -import java.net.URL; -import java.security.KeyStore; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ScheduledExecutorService; - -import javax.naming.Binding; -import javax.naming.Context; -import javax.naming.Name; -import javax.naming.NameClassPair; -import javax.naming.NameParser; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLContext; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.core.Configuration; - -/** - * This is the context used for looking up and invoking remote EJBs via - * REST in Payara 5.191+. - * - *

- * Note that at the moment only the lookup methods are implemented. - * - *

- * This context supports the following Payara specific properties in its environment: - * - *

    - *
  • fish.payara.connectTimeout
  • - *
  • fish.payara.executorService
  • - *
  • fish.payara.hostnameVerifier
  • - *
  • fish.payara.keyStore
  • - *
  • fish.payara.readTimeout
  • - *
  • fish.payara.hostnameVerifier
  • - *
  • fish.payara.scheduledExecutorService"
  • - *
  • fish.payara.sslContext
  • - *
  • fish.payara.trustStore
  • - *
  • fish.payara.withConfig
  • - *
- * - * All properties corresponds to the similarly named settings on the JAX-RS {@link ClientBuilder}. - * Times are in microseconds, and values can either be given as Strings, number values or object instances. - * - * @author Arjan Tijms - * @since Payara 5.191 - * - */ -class RemoteEJBContext implements Context { - - private Hashtable environment; - - @SuppressWarnings("unchecked") - public RemoteEJBContext(Hashtable environment) { - this.environment = (Hashtable) environment; - } - - @Override - public Object lookup(Name name) throws NamingException { - return lookup(name.toString()); - } - - @Override - public Object lookup(String name) throws NamingException { - String url = (String) environment.get(PROVIDER_URL); - - try { - // Get client build with all optional config applied - ClientBuilder clientBuilder = getClientBuilder(); - - // For the lookup do a call to the remote server first to obtain - // the remote business interface class name given a JNDI lookup name. - // The JNDI lookup name normally does not give us this interface name. - // This also allows us to check the JNDI name indeed resolves before - // we create a proxy and return it here. - - Map payload = new HashMap<>(); - payload.put("lookup", name); - - URI remotePayaraURI = new URL(url).toURI(); - - String className = - clientBuilder - .build() - .target(remotePayaraURI) - .path("ejb") - .path("lookup") - .request() - .post(Entity.entity(payload, APPLICATION_JSON)) - .readEntity(String.class); - - // After we have obtained the class name of the remote interface, generate - // a proxy based on it. - - return EjbRestProxyFactory.newProxy( - Class.forName(className), - clientBuilder.build() - .target(remotePayaraURI) - .path("ejb") - .path("invoke"), - name, - new HashMap(environment) - ); - - } catch (Exception e) { - throw newNamingException(name, e); - } - } - - private ClientBuilder getClientBuilder() throws ClassNotFoundException, InstantiationException, IllegalAccessException { - ClientBuilder clientBuilder = ClientBuilder.newBuilder(); - - if (environment.containsKey(FISH_PAYARA_CONNECT_TIMEOUT)) { - clientBuilder.connectTimeout(getLong(environment.get(FISH_PAYARA_CONNECT_TIMEOUT)).longValue(), MICROSECONDS); - } - - if (environment.contains(FISH_PAYARA_EXECUTOR_SERVICE)) { - clientBuilder.executorService(getInstance(environment.get(FISH_PAYARA_EXECUTOR_SERVICE), ExecutorService.class)); - } - - if (environment.contains(FISH_PAYARA_HOSTNAME_VERIFIER)) { - clientBuilder.hostnameVerifier(getInstance(environment.get(FISH_PAYARA_HOSTNAME_VERIFIER), HostnameVerifier.class)); - } - - if (environment.contains(FISH_PAYARA_KEY_STORE)) { - clientBuilder.keyStore(getInstance(environment.get(FISH_PAYARA_KEY_STORE), KeyStore.class), getPassword(environment.get("keyStorePassword"))); - } - - if (environment.containsKey(FISH_PAYARA_READ_TIMEOUT)) { - clientBuilder.readTimeout(getLong(environment.get(FISH_PAYARA_READ_TIMEOUT)).longValue(), MICROSECONDS); - } - - if (environment.contains(FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE)) { - clientBuilder.scheduledExecutorService(getInstance(environment.get(FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE), ScheduledExecutorService.class)); - } - - if (environment.contains(FISH_PAYARA_SSL_CONTEXT)) { - clientBuilder.sslContext(getInstance(environment.get(FISH_PAYARA_SSL_CONTEXT), SSLContext.class)); - } - - if (environment.contains(FISH_PAYARA_TRUST_STORE)) { - clientBuilder.trustStore(getInstance(environment.get(FISH_PAYARA_TRUST_STORE), KeyStore.class)); - } - - if (environment.contains(FISH_PAYARA_WITH_CONFIG)) { - clientBuilder.withConfig(getInstance(environment.get(FISH_PAYARA_WITH_CONFIG), Configuration.class)); - } - - return clientBuilder; - } - - private NamingException newNamingException(String name, Exception cause) { - NamingException namingException = new NamingException("Could not lookup :" + name); - namingException.initCause(cause); - - return namingException; - } - - private T getInstance(Object value, Class clazz) throws ClassNotFoundException, InstantiationException, IllegalAccessException { - if (clazz.isInstance(value)) { - return clazz.cast(value); - } - - if (value instanceof String) { - return clazz.cast(Class.forName((String)value).newInstance()); - } - - throw new IllegalStateException("Value " + value + " has to be of type String or " + clazz); - } - - private Long getLong(Object value) { - if (value instanceof Number) { - return ((Number) value).longValue(); - } - - if (value instanceof String) { - return Long.valueOf((String) value); - } - - throw new IllegalStateException("Value " + value + " has to be of type String or Number"); - } - - private char[] getPassword(Object value) { - if (value instanceof String) { - return ((String) value).toCharArray(); - } - - if (value instanceof char[]) { - return (char[]) value; - } - throw new IllegalArgumentException("No password provided"); - - } - - @Override - public void bind(Name name, Object obj) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public void bind(String name, Object obj) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public void rebind(Name name, Object obj) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public void rebind(String name, Object obj) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public void unbind(Name name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public void unbind(String name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public void rename(Name oldName, Name newName) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public void rename(String oldName, String newName) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public NamingEnumeration list(Name name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public NamingEnumeration list(String name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public NamingEnumeration listBindings(Name name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public NamingEnumeration listBindings(String name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public void destroySubcontext(Name name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public void destroySubcontext(String name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public Context createSubcontext(Name name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public Context createSubcontext(String name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public Object lookupLink(Name name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public Object lookupLink(String name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public NameParser getNameParser(Name name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public NameParser getNameParser(String name) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public Name composeName(Name name, Name prefix) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public String composeName(String name, String prefix) throws NamingException { - throw new UnsupportedOperationException(); - } - - @Override - public Object addToEnvironment(String propName, Object propVal) throws NamingException { - return environment.put(propName, propVal); - } - - @Override - public Object removeFromEnvironment(String propName) throws NamingException { - return environment.remove(propName); - } - - @Override - public Hashtable getEnvironment() throws NamingException { - return environment; - } - - @Override - public void close() throws NamingException { - environment.clear(); - } - - @Override - public String getNameInNamespace() throws NamingException { - throw new UnsupportedOperationException(); - } - -} diff --git a/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java b/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java deleted file mode 100644 index ed0518333dd..00000000000 --- a/appserver/ejb/ejb-rest-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can - * obtain a copy of the License at - * https://github.com/payara/Payara/blob/master/LICENSE.txt - * See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at glassfish/legal/LICENSE.txt. - * - * GPL Classpath Exception: - * The Payara Foundation designates this particular file as subject to the "Classpath" - * exception as provided by the Payara Foundation in the GPL Version 2 section of the License - * file that accompanied this code. - * - * Modifications: - * If applicable, add the following below the License Header, with the fields - * enclosed by brackets [] replaced by your own identifying information: - * "Portions Copyright [year] [name of copyright owner]" - * - * Contributor(s): - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ -package fish.payara.ejb.rest.client; - -import java.util.Hashtable; - -import javax.naming.Context; -import javax.naming.NamingException; -import javax.naming.spi.InitialContextFactory; - -/** - * This is the context factory that creates the context used for looking up and invoking - * remote EJBs. - * - *

- * Clients wanting to use remote EJB in this way should set the property in the initial context - * environment as follows: - * - *

- * 
- *   Hashtable<String, String> environment = new Hashtable<>();
- *   environment.put(INITIAL_CONTEXT_FACTORY, "fish.payara.ejb.rest.client.RemoteEJBContextFactory");
- *    ...
- *   new InitialContext(environment);
- * 
- * 
- * - * @author Arjan Tijms - * @since Payara 5.191 - */ -public class RemoteEJBContextFactory implements InitialContextFactory { - - public static final String FISH_PAYARA_WITH_CONFIG = "fish.payara.withConfig"; - public static final String FISH_PAYARA_TRUST_STORE = "fish.payara.trustStore"; - public static final String FISH_PAYARA_SSL_CONTEXT = "fish.payara.sslContext"; - public static final String FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE = "fish.payara.scheduledExecutorService"; - public static final String FISH_PAYARA_READ_TIMEOUT = "fish.payara.readTimeout"; - public static final String FISH_PAYARA_KEY_STORE = "fish.payara.keyStore"; - public static final String FISH_PAYARA_HOSTNAME_VERIFIER = "fish.payara.hostnameVerifier"; - public static final String FISH_PAYARA_EXECUTOR_SERVICE = "fish.payara.executorService"; - public static final String FISH_PAYARA_CONNECT_TIMEOUT = "fish.payara.connectTimeout"; - - @Override - public Context getInitialContext(Hashtable environment) throws NamingException { - return new RemoteEJBContext(environment); - } - -} diff --git a/appserver/ejb/ejb-rest-remoting/endpoint/pom.xml b/appserver/ejb/ejb-rest-remoting/endpoint/pom.xml deleted file mode 100644 index 7aa4a287158..00000000000 --- a/appserver/ejb/ejb-rest-remoting/endpoint/pom.xml +++ /dev/null @@ -1,91 +0,0 @@ - - - - - 4.0.0 - - - fish.payara.ejb.http - ejb-http-remoting - 5.192-SNAPSHOT - - - ejb-http-endpoint - war - - EJB - HTTP Endpoint - - This module contains the endpoint that services HTTP commands from the client (fish.payara.ejb.http:ejb-http-client) and looks EJBs up and invokes them. - - It contains a mini web application that is picked up by the domain template (org.glassfish.main.admin:nucleus-domain) which places it in the - glassfish/domains/[domainname]/endpoints/ejb-invoker folder. - - - - - javax.servlet - javax.servlet-api - provided - - - javax.json.bind - javax.json.bind-api - provided - - - javax.json - javax.json-api - provided - - - javax.ws.rs - javax.ws.rs-api - provided - - - org.glassfish.main.security - security-ee - ${project.version} - provided - - - - diff --git a/appserver/ejb/ejb-rest-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java b/appserver/ejb/ejb-rest-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java deleted file mode 100644 index f0c16d2906e..00000000000 --- a/appserver/ejb/ejb-rest-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can - * obtain a copy of the License at - * https://github.com/payara/Payara/blob/master/LICENSE.txt - * See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at glassfish/legal/LICENSE.txt. - * - * GPL Classpath Exception: - * The Payara Foundation designates this particular file as subject to the "Classpath" - * exception as provided by the Payara Foundation in the GPL Version 2 section of the License - * file that accompanied this code. - * - * Modifications: - * If applicable, add the following below the License Header, with the fields - * enclosed by brackets [] replaced by your own identifying information: - * "Portions Copyright [year] [name of copyright owner]" - * - * Contributor(s): - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ -package fish.payara.ejb.invoke; - -import static javax.naming.Context.SECURITY_CREDENTIALS; -import static javax.naming.Context.SECURITY_PRINCIPAL; -import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; - -import java.io.IOException; -import java.util.Base64; -import java.util.List; -import java.util.function.Supplier; - -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonString; -import javax.json.JsonValue; -import javax.json.bind.JsonbBuilder; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.glassfish.internal.api.Globals; -import org.glassfish.internal.data.ApplicationRegistry; - -import com.sun.enterprise.security.ee.auth.login.ProgrammaticLogin; - -/** - */ -@WebServlet("/ejb/*") -public class InvokeEJBServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - response.getWriter().append("Served at: ").append(request.getContextPath()); - } - - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - - JsonObject requestPayload = - Json.createReader(request.getReader()) - .readObject(); - - if (request.getRequestURI().endsWith("lookup")) { - boolean success = excuteInAppContext(() -> { - - try { - response.getWriter().print( - new InitialContext().lookup(requestPayload.getString("lookup")) - .getClass() - .getInterfaces()[0] - .getName()); - return true; - } catch (IOException | NamingException e) { - // Ignore for now - } - - return false; - }); - - if (!success) { - response.sendError(SC_INTERNAL_SERVER_ERROR, "Name " + requestPayload.getString("lookup") + " not found when doing initial lookup"); - } - - return; - } - - // Convert JSON encoded method parameter type names to actually Class instances - Class[] argTypes = - requestPayload.getJsonArray("argTypes").stream() - .map(e -> toClass(e)) - .toArray(Class[]::new); - - // Convert JSON encoded method parameter values to their object instances - List jsonArgValues = requestPayload.getJsonArray("argValues"); - Object[] argValues = new Object[argTypes.length]; - for (int i = 0; i < jsonArgValues.size(); i++) { - argValues[i] = toObject(jsonArgValues.get(i), argTypes[i]); - } - - boolean success = excuteInAppContext(() -> { - try { - // Obtain the target EJB that we're going to invoke - Object bean = new InitialContext().lookup(requestPayload.getString("lookup")); - - // Authenticates the caller and if successful sets the security context - // *for the outgoing EJB call*. In other words, the security context for this - // Servlet will not be changed. - if (requestPayload.containsKey(SECURITY_PRINCIPAL)) { - ProgrammaticLogin login = new ProgrammaticLogin(); - login.login( - base64Decode(requestPayload.getString(SECURITY_PRINCIPAL)), - base64Decode(requestPayload.getString(SECURITY_CREDENTIALS)), - null, true); - } - - // Actually invoke the target EJB - Object result = - bean.getClass() - .getMethod(requestPayload.getString("method"), argTypes) - .invoke(bean, argValues); - - response.setContentType(APPLICATION_JSON); - response.getWriter().print(result instanceof String? result : JsonbBuilder.create().toJson(result)); - - return true; - - } catch (Exception e) { - e.printStackTrace(); - } - - return false; - }); - - if (!success) { - response.sendError(SC_INTERNAL_SERVER_ERROR, "Name " + requestPayload.getString("lookup") + " not found when invoking"); - } - } - - private Class toClass(JsonValue classNameValue) { - try { - String className = null; - if (classNameValue instanceof JsonString) { - className = ((JsonString) classNameValue).getString(); - } else { - className = classNameValue.toString().replace("\"", ""); - } - - return Class.forName(className); - } catch (ClassNotFoundException e) { - throw new IllegalStateException(e); - } - } - - private Object toObject(JsonValue objectValue, Class type) { - return JsonbBuilder - .create() - .fromJson(objectValue.toString(), type); - } - - private boolean excuteInAppContext(Supplier body) { - ApplicationRegistry registry = Globals.get(ApplicationRegistry.class); - - for (String applicationName : registry.getAllApplicationNames()) { - ClassLoader existingContextClassLoader = Thread.currentThread().getContextClassLoader(); - try { - - Thread.currentThread().setContextClassLoader(registry.get(applicationName).getAppClassLoader()); - - try { - if (body.get()) { - return true; - } - } catch (Exception e) { - // ignore - } - - } finally { - if (existingContextClassLoader != null) { - Thread.currentThread().setContextClassLoader(existingContextClassLoader); - } - } - - } - - return false; - } - - private static String base64Decode(String input) { - return new String(Base64.getDecoder().decode(input)); - } - -} diff --git a/appserver/ejb/ejb-rest-remoting/pom.xml b/appserver/ejb/ejb-rest-remoting/pom.xml deleted file mode 100755 index 7f8c10c3bca..00000000000 --- a/appserver/ejb/ejb-rest-remoting/pom.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - 4.0.0 - - org.glassfish.main.ejb - ejb - 5.192-SNAPSHOT - - - fish.payara.ejb.http - ejb-http-remoting - pom - - EJB - HTTP - - - This module is the parent module for the lightweight HTTP-based EJB remote system. It contains an admin - module that has CLI (AsAdmin) commands for configuring the server side. An endpoint module that implements - the endpoint which receives the HTTP calls from the client and invoked an EJB, and finally a client module - which is used by the client to lookup and invoke EJB methods on a proxy. - - - - admin - endpoint - client - - - From 7211689dbd02dfc8754a16ca9d9c51cdbe60d080 Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Thu, 7 Mar 2019 16:33:59 +0000 Subject: [PATCH 007/108] Folder renamed - updated file paths --- appserver/ejb/ejb-http-remoting/admin/pom.xml | 77 ++++ .../rest/admin/DisableEjbInvokerCommand.java | 128 ++++++ .../rest/admin/EnableEjbInvokerCommand.java | 129 ++++++ .../ejb/ejb-http-remoting/client/pom.xml | 90 ++++ .../ejb/rest/client/EjbRestProxyFactory.java | 86 ++++ .../ejb/rest/client/EjbRestProxyHandler.java | 153 +++++++ .../ejb/rest/client/RemoteEJBContext.java | 387 ++++++++++++++++++ .../rest/client/RemoteEJBContextFactory.java | 85 ++++ .../ejb/ejb-http-remoting/endpoint/pom.xml | 91 ++++ .../payara/ejb/invoke/InvokeEJBServlet.java | 215 ++++++++++ appserver/ejb/ejb-http-remoting/pom.xml | 68 +++ 11 files changed, 1509 insertions(+) create mode 100644 appserver/ejb/ejb-http-remoting/admin/pom.xml create mode 100644 appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java create mode 100644 appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java create mode 100644 appserver/ejb/ejb-http-remoting/client/pom.xml create mode 100644 appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java create mode 100644 appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java create mode 100644 appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java create mode 100644 appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java create mode 100644 appserver/ejb/ejb-http-remoting/endpoint/pom.xml create mode 100644 appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java create mode 100755 appserver/ejb/ejb-http-remoting/pom.xml diff --git a/appserver/ejb/ejb-http-remoting/admin/pom.xml b/appserver/ejb/ejb-http-remoting/admin/pom.xml new file mode 100644 index 00000000000..3d971033bc3 --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/admin/pom.xml @@ -0,0 +1,77 @@ + + + + + 4.0.0 + + + fish.payara.ejb.http + ejb-http-remoting + 5.192-SNAPSHOT + + + ejb-http-admin + glassfish-jar + + EJB - HTTP Admin + + CLI (Asadmin) commands to configure the EJB HTTP endpoint. This contains commands to enable and disable the endpoint that invokes an EJB and + to set the context root on which this endpoint is listening. + + + + + org.glassfish.main.deployment + deployment-autodeploy + ${project.version} + + + org.glassfish.main.common + internal-api + ${project.version} + + + javax + javaee-api + ${javaee.api.version} + + + diff --git a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java new file mode 100644 index 00000000000..9d26352ab71 --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java @@ -0,0 +1,128 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.ejb.rest.admin; + +import static org.glassfish.config.support.CommandTarget.CLUSTER; +import static org.glassfish.config.support.CommandTarget.CLUSTERED_INSTANCE; +import static org.glassfish.config.support.CommandTarget.CONFIG; +import static org.glassfish.config.support.CommandTarget.DAS; +import static org.glassfish.config.support.CommandTarget.DEPLOYMENT_GROUP; +import static org.glassfish.config.support.CommandTarget.STANDALONE_INSTANCE; +import static org.glassfish.deployment.autodeploy.AutoDeployer.getNameFromFilePath; + +import java.nio.file.Path; + +import javax.inject.Inject; + +import com.sun.enterprise.config.serverbeans.Domain; +import org.glassfish.api.ActionReport; +import org.glassfish.api.Param; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.RuntimeType; +import org.glassfish.api.admin.ServerEnvironment; +import org.glassfish.config.support.TargetType; +import org.glassfish.deployment.autodeploy.AutoDeployer.AutodeploymentStatus; +import org.glassfish.deployment.autodeploy.AutoUndeploymentOperation; +import org.glassfish.hk2.api.PerLookup; +import org.glassfish.hk2.api.ServiceLocator; +import org.jvnet.hk2.annotations.Service; + +/** + * This command disables the EJB invoker endpoint. + * + *

+ * This happens by undeploying the small application in /domains/[domain]/endpoints/ejb-invoker. + * Note that by default this application is not deployed. The default context root of this application is + * /ejb-invoker, but it may have been set to a different root by the {@link EnableEjbInvokerCommand} + * command. + * + * @author Arjan Tijms + * + */ +@Service(name = "disable-ejb-invoker") +@PerLookup +@ExecuteOn(RuntimeType.DAS) +@TargetType({ DAS, STANDALONE_INSTANCE, CLUSTER, CLUSTERED_INSTANCE, CONFIG, DEPLOYMENT_GROUP }) +public class DisableEjbInvokerCommand implements AdminCommand { + + private final String ENDPOINTS = "endpoints"; + private final String EJB_INVOKER = "ejb-invoker"; + + @Param(optional = true) + public String target; + + @Inject + private ServerEnvironment serverEnvironment; + + @Inject + private ServiceLocator serviceLocator; + + @Inject + private Domain domain; + + @Override + public void execute(AdminCommandContext context) { + + Path endPointsPath = serverEnvironment.getInstanceRoot().toPath().resolve(ENDPOINTS); + Path ejbInvokerPath = endPointsPath.resolve(EJB_INVOKER); + + AutoUndeploymentOperation autoUndeploymentOperation = AutoUndeploymentOperation.newInstance( + serviceLocator, + ejbInvokerPath.toFile(), + getNameFromFilePath(endPointsPath.toFile(), ejbInvokerPath.toFile()), + target); + + AutodeploymentStatus deploymentStatus = autoUndeploymentOperation.run(); + + ActionReport report = context.getActionReport(); + report.setActionExitCode(deploymentStatus.getExitCode()); + + if (deploymentStatus.getExitCode().equals(ActionReport.ExitCode.FAILURE)) { + if (domain.getApplications().getApplication("ejb-invoker") == null) { + report.appendMessage("\nEJB Invoker is not enabled on any target"); + } else { + report.appendMessage("\nFailed to disable Ejb Invoker - was it enabled on the specified target?"); + } + } + } + +} diff --git a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java new file mode 100644 index 00000000000..99c35c0bfa3 --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java @@ -0,0 +1,129 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.ejb.rest.admin; + +import static org.glassfish.config.support.CommandTarget.CLUSTER; +import static org.glassfish.config.support.CommandTarget.CLUSTERED_INSTANCE; +import static org.glassfish.config.support.CommandTarget.CONFIG; +import static org.glassfish.config.support.CommandTarget.DAS; +import static org.glassfish.config.support.CommandTarget.DEPLOYMENT_GROUP; +import static org.glassfish.config.support.CommandTarget.STANDALONE_INSTANCE; + +import javax.inject.Inject; + +import com.sun.enterprise.config.serverbeans.Domain; +import org.glassfish.api.ActionReport; +import org.glassfish.api.Param; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.RuntimeType; +import org.glassfish.api.admin.ServerEnvironment; +import org.glassfish.config.support.TargetType; +import org.glassfish.deployment.autodeploy.AutoDeployer.AutodeploymentStatus; +import org.glassfish.deployment.autodeploy.AutoDeploymentOperation; +import org.glassfish.hk2.api.PerLookup; +import org.glassfish.hk2.api.ServiceLocator; +import org.jvnet.hk2.annotations.Service; + +/** + * This command enables the EJB invoker endpoint and optionally allows it to set an + * alternative context root. + * + *

+ * This happens by the deploying a small application in /domains/[domain]/endpoints/ejb-invoker + * which by default is not deployed. The default context root of this application is + * /ejb-invoker. + * + * @author Arjan Tijms + * + */ +@Service(name = "enable-ejb-invoker") +@PerLookup +@ExecuteOn(RuntimeType.DAS) +@TargetType({ DAS, STANDALONE_INSTANCE, CLUSTER, CLUSTERED_INSTANCE, CONFIG, DEPLOYMENT_GROUP }) +public class EnableEjbInvokerCommand implements AdminCommand { + + private final String ENDPOINT = "endpoints/ejb-invoker"; + + @Param(name = "contextRoot", primary = true, optional = true) + private String contextRoot; + + @Param(optional = true) + public String target; + + @Inject + private ServerEnvironment serverEnvironment; + + @Inject + private ServiceLocator serviceLocator; + + @Inject + private Domain domain; + + @Override + public void execute(AdminCommandContext context) { + AutoDeploymentOperation autoDeploymentOperation = AutoDeploymentOperation.newInstance( + serviceLocator, + serverEnvironment.getInstanceRoot().toPath().resolve(ENDPOINT).toFile(), + getDefaultVirtualServer(), + target, + contextRoot + ); + + if (domain.getApplications().getApplication("ejb-invoker") == null) { + AutodeploymentStatus deploymentStatus = autoDeploymentOperation.run(); + ActionReport report = context.getActionReport(); + report.setActionExitCode(deploymentStatus.getExitCode()); + } else { + ActionReport report = context.getActionReport(); + report.setActionExitCode(ActionReport.ExitCode.WARNING); + report.setMessage("EJB Invoker is already deployed on at least one target, please edit it as you would a " + + "normal application using the create-application-ref, delete-application-ref, " + + "or update-application-ref commands"); + } + } + + private String getDefaultVirtualServer() { + // XXX write this? + return null; + } + +} diff --git a/appserver/ejb/ejb-http-remoting/client/pom.xml b/appserver/ejb/ejb-http-remoting/client/pom.xml new file mode 100644 index 00000000000..e52190577b9 --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/client/pom.xml @@ -0,0 +1,90 @@ + + + + 4.0.0 + + + fish.payara.ejb.http + ejb-rest-remoting + 5.192-SNAPSHOT + + + ejb-http-client + + EJB - HTTP Client + + Module providing support for the EJB HTTP Client. This contains an InitialContext based lookup mechanism that uses HTTP calls back + to Payara to lookup EJB beans, as well as a proxy mechanism to invoke methods on an EJB, which will be sent via HTTP all well + to Payara. + + + + + + org.apache.felix + maven-bundle-plugin + true + true + + + fish.payara.ejb.http.client.*;version=${project.version} + + true + + + + + + + + org.glassfish.jersey.core + jersey-client + + + org.glassfish.jersey.core + jersey-common + + + javax.json + javax.json-api + + + diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java new file mode 100644 index 00000000000..58592bd0339 --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java @@ -0,0 +1,86 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.ejb.rest.client; + +import static java.lang.reflect.Proxy.newProxyInstance; +import static java.security.AccessController.doPrivileged; +import static java.util.Collections.emptyList; +import static org.glassfish.jersey.internal.util.ReflectionHelper.getClassLoaderPA; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Cookie; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; + +/** + * This class generates a type-safe proxy for a given remote EJB interface. + * + *

+ * Calls on this proxy are handled by {@link EjbRestProxyHandler}. + * + * + * @author Arjan Tijms + * @since Payara 5.191 + * + */ +final class EjbRestProxyFactory { + + private static final MultivaluedMap EMPTY_MULTI_MAP = new MultivaluedHashMap<>(); + + public static C newProxy(Class remoteBusinessInterface, WebTarget target, String lookup, Map jndiOptions) { + return newProxy(remoteBusinessInterface, target, EMPTY_MULTI_MAP, emptyList(), lookup, jndiOptions); + } + + @SuppressWarnings("unchecked") + public static C newProxy(Class remoteBusinessInterface, WebTarget target, MultivaluedMap headers, List cookies, String lookup, Map jndiOptions) { + return (C) + newProxyInstance(doPrivileged(getClassLoaderPA(remoteBusinessInterface)), + new Class[] { remoteBusinessInterface }, + new EjbRestProxyHandler(addPathFromClass(remoteBusinessInterface, target), headers, cookies, lookup, jndiOptions)); + } + + private static WebTarget addPathFromClass(Class clazz, WebTarget target) { + return target.path(clazz.getSimpleName()); + } + +} diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java new file mode 100644 index 00000000000..23c5f67d719 --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java @@ -0,0 +1,153 @@ +package fish.payara.ejb.rest.client; + +import static javax.naming.Context.SECURITY_CREDENTIALS; +import static javax.naming.Context.SECURITY_PRINCIPAL; +import static javax.ws.rs.HttpMethod.POST; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.util.Base64; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Future; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Cookie; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; + +/** + * This class handles invocations (method calls) on a proxy generated by {@link EjbRestProxyFactory}. + * + *

+ * This proxy uses REST calls to an endpoint in a given remote Payara server. + * + * @author Arjan Tijms + * @since Payara 5.191 + * + */ +class EjbRestProxyHandler implements InvocationHandler { + + private final WebTarget target; + private final MultivaluedMap headers; + private final List cookies; + private final String lookup; + private final Map jndiOptions; + + EjbRestProxyHandler(WebTarget target, MultivaluedMap headers, List cookies, String lookup, Map jndiOptions) { + this.target = target; + this.headers = headers; + this.cookies = cookies; + this.lookup = lookup; + this.jndiOptions = jndiOptions; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] argValues) throws Throwable { + + // Check for methods we should not proxy first + + if (argValues == null && method.getName().equals("toString")) { + return toString(); + } + + if (argValues == null && method.getName().equals("hashCode")) { + // unique instance in the JVM, and no need to override + return hashCode(); + } + + if (argValues != null && argValues.length == 1 && method.getName().equals("equals")) { + // unique instance in the JVM, and no need to override + return equals(argValues[0]); + } + + // Valid method, do invoke it remotely + return doRemoteInvoke(proxy, method, argValues); + } + + public Object doRemoteInvoke(Object proxy, Method method, Object[] argValues) throws Throwable { + // HTTP method name; we're always using POST to invoke remote EJBs + String httpMethod = POST; + + // The bare payload being sent + Map payload = new HashMap<>(); + payload.put("lookup", lookup); + payload.put("method", method.getName()); + payload.put("argTypes", method.getParameterTypes()); + payload.put("argValues", argValues == null? new Object[0] : argValues); + + if (jndiOptions.containsKey(SECURITY_PRINCIPAL)) { + payload.put(SECURITY_PRINCIPAL, base64Encode(jndiOptions.get(SECURITY_PRINCIPAL))); + } + + if (jndiOptions.containsKey(SECURITY_CREDENTIALS)) { + payload.put(SECURITY_CREDENTIALS, base64Encode(jndiOptions.get(SECURITY_CREDENTIALS))); + } + + // Payload wrapped as entity so it'll be encoded in JSON + Entity entity = Entity.entity(payload, APPLICATION_JSON); + + // Response type + Class responseType = method.getReturnType(); + GenericType responseGenericType = new GenericType<>(method.getGenericReturnType()); + + // Create a new UriBuilder appending the name from the method + WebTarget newTarget = addPathFromMethod(method, target); + + // Start request + Invocation.Builder builder = newTarget.request(); + + // Set optional headers and cookies + builder.headers(new MultivaluedHashMap(this.headers)); + for (Cookie cookie : new LinkedList<>(this.cookies)) { + builder = builder.cookie(cookie); + } + + // Call remote server + + if (responseType.isAssignableFrom(CompletionStage.class)) { + + // Reactive call - the actual response type is T from CompletionStage + return builder.rx().method(httpMethod, entity, getResponseParameterizedType(method, responseGenericType)); + } else if (responseType.isAssignableFrom(Future.class)) { + + // Asynchronous call - the actual response type is T from Future + return builder.async().method(httpMethod, entity, getResponseParameterizedType(method, responseGenericType)); + } + + // Synchronous call + return builder.method(httpMethod, entity, responseGenericType); + } + + private GenericType getResponseParameterizedType(Method method, GenericType responseGenericType) { + if (method.getGenericReturnType() instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) method.getGenericReturnType(); + + return new GenericType<>(parameterizedType.getActualTypeArguments()[0]); + } + + return responseGenericType; + } + + private static String base64Encode(Object input) { + return Base64.getEncoder().encodeToString(input.toString().getBytes()); + } + + private static WebTarget addPathFromMethod(Method method, WebTarget target) { + return target.path(method.getName()); + } + + @Override + public String toString() { + return target.toString(); + } + +} diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java new file mode 100644 index 00000000000..f961a081252 --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java @@ -0,0 +1,387 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.ejb.rest.client; + +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_CONNECT_TIMEOUT; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_EXECUTOR_SERVICE; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_HOSTNAME_VERIFIER; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_KEY_STORE; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_READ_TIMEOUT; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_SSL_CONTEXT; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_TRUST_STORE; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_WITH_CONFIG; +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +import java.net.URI; +import java.net.URL; +import java.security.KeyStore; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledExecutorService; + +import javax.naming.Binding; +import javax.naming.Context; +import javax.naming.Name; +import javax.naming.NameClassPair; +import javax.naming.NameParser; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Configuration; + +/** + * This is the context used for looking up and invoking remote EJBs via + * REST in Payara 5.191+. + * + *

+ * Note that at the moment only the lookup methods are implemented. + * + *

+ * This context supports the following Payara specific properties in its environment: + * + *

    + *
  • fish.payara.connectTimeout
  • + *
  • fish.payara.executorService
  • + *
  • fish.payara.hostnameVerifier
  • + *
  • fish.payara.keyStore
  • + *
  • fish.payara.readTimeout
  • + *
  • fish.payara.hostnameVerifier
  • + *
  • fish.payara.scheduledExecutorService"
  • + *
  • fish.payara.sslContext
  • + *
  • fish.payara.trustStore
  • + *
  • fish.payara.withConfig
  • + *
+ * + * All properties corresponds to the similarly named settings on the JAX-RS {@link ClientBuilder}. + * Times are in microseconds, and values can either be given as Strings, number values or object instances. + * + * @author Arjan Tijms + * @since Payara 5.191 + * + */ +class RemoteEJBContext implements Context { + + private Hashtable environment; + + @SuppressWarnings("unchecked") + public RemoteEJBContext(Hashtable environment) { + this.environment = (Hashtable) environment; + } + + @Override + public Object lookup(Name name) throws NamingException { + return lookup(name.toString()); + } + + @Override + public Object lookup(String name) throws NamingException { + String url = (String) environment.get(PROVIDER_URL); + + try { + // Get client build with all optional config applied + ClientBuilder clientBuilder = getClientBuilder(); + + // For the lookup do a call to the remote server first to obtain + // the remote business interface class name given a JNDI lookup name. + // The JNDI lookup name normally does not give us this interface name. + // This also allows us to check the JNDI name indeed resolves before + // we create a proxy and return it here. + + Map payload = new HashMap<>(); + payload.put("lookup", name); + + URI remotePayaraURI = new URL(url).toURI(); + + String className = + clientBuilder + .build() + .target(remotePayaraURI) + .path("ejb") + .path("lookup") + .request() + .post(Entity.entity(payload, APPLICATION_JSON)) + .readEntity(String.class); + + // After we have obtained the class name of the remote interface, generate + // a proxy based on it. + + return EjbRestProxyFactory.newProxy( + Class.forName(className), + clientBuilder.build() + .target(remotePayaraURI) + .path("ejb") + .path("invoke"), + name, + new HashMap(environment) + ); + + } catch (Exception e) { + throw newNamingException(name, e); + } + } + + private ClientBuilder getClientBuilder() throws ClassNotFoundException, InstantiationException, IllegalAccessException { + ClientBuilder clientBuilder = ClientBuilder.newBuilder(); + + if (environment.containsKey(FISH_PAYARA_CONNECT_TIMEOUT)) { + clientBuilder.connectTimeout(getLong(environment.get(FISH_PAYARA_CONNECT_TIMEOUT)).longValue(), MICROSECONDS); + } + + if (environment.contains(FISH_PAYARA_EXECUTOR_SERVICE)) { + clientBuilder.executorService(getInstance(environment.get(FISH_PAYARA_EXECUTOR_SERVICE), ExecutorService.class)); + } + + if (environment.contains(FISH_PAYARA_HOSTNAME_VERIFIER)) { + clientBuilder.hostnameVerifier(getInstance(environment.get(FISH_PAYARA_HOSTNAME_VERIFIER), HostnameVerifier.class)); + } + + if (environment.contains(FISH_PAYARA_KEY_STORE)) { + clientBuilder.keyStore(getInstance(environment.get(FISH_PAYARA_KEY_STORE), KeyStore.class), getPassword(environment.get("keyStorePassword"))); + } + + if (environment.containsKey(FISH_PAYARA_READ_TIMEOUT)) { + clientBuilder.readTimeout(getLong(environment.get(FISH_PAYARA_READ_TIMEOUT)).longValue(), MICROSECONDS); + } + + if (environment.contains(FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE)) { + clientBuilder.scheduledExecutorService(getInstance(environment.get(FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE), ScheduledExecutorService.class)); + } + + if (environment.contains(FISH_PAYARA_SSL_CONTEXT)) { + clientBuilder.sslContext(getInstance(environment.get(FISH_PAYARA_SSL_CONTEXT), SSLContext.class)); + } + + if (environment.contains(FISH_PAYARA_TRUST_STORE)) { + clientBuilder.trustStore(getInstance(environment.get(FISH_PAYARA_TRUST_STORE), KeyStore.class)); + } + + if (environment.contains(FISH_PAYARA_WITH_CONFIG)) { + clientBuilder.withConfig(getInstance(environment.get(FISH_PAYARA_WITH_CONFIG), Configuration.class)); + } + + return clientBuilder; + } + + private NamingException newNamingException(String name, Exception cause) { + NamingException namingException = new NamingException("Could not lookup :" + name); + namingException.initCause(cause); + + return namingException; + } + + private T getInstance(Object value, Class clazz) throws ClassNotFoundException, InstantiationException, IllegalAccessException { + if (clazz.isInstance(value)) { + return clazz.cast(value); + } + + if (value instanceof String) { + return clazz.cast(Class.forName((String)value).newInstance()); + } + + throw new IllegalStateException("Value " + value + " has to be of type String or " + clazz); + } + + private Long getLong(Object value) { + if (value instanceof Number) { + return ((Number) value).longValue(); + } + + if (value instanceof String) { + return Long.valueOf((String) value); + } + + throw new IllegalStateException("Value " + value + " has to be of type String or Number"); + } + + private char[] getPassword(Object value) { + if (value instanceof String) { + return ((String) value).toCharArray(); + } + + if (value instanceof char[]) { + return (char[]) value; + } + throw new IllegalArgumentException("No password provided"); + + } + + @Override + public void bind(Name name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void bind(String name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void rebind(Name name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void rebind(String name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void unbind(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void unbind(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void rename(Name oldName, Name newName) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void rename(String oldName, String newName) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NamingEnumeration list(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NamingEnumeration list(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NamingEnumeration listBindings(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NamingEnumeration listBindings(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void destroySubcontext(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void destroySubcontext(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Context createSubcontext(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Context createSubcontext(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Object lookupLink(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Object lookupLink(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NameParser getNameParser(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NameParser getNameParser(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Name composeName(Name name, Name prefix) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public String composeName(String name, String prefix) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Object addToEnvironment(String propName, Object propVal) throws NamingException { + return environment.put(propName, propVal); + } + + @Override + public Object removeFromEnvironment(String propName) throws NamingException { + return environment.remove(propName); + } + + @Override + public Hashtable getEnvironment() throws NamingException { + return environment; + } + + @Override + public void close() throws NamingException { + environment.clear(); + } + + @Override + public String getNameInNamespace() throws NamingException { + throw new UnsupportedOperationException(); + } + +} diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java new file mode 100644 index 00000000000..ed0518333dd --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java @@ -0,0 +1,85 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.ejb.rest.client; + +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.spi.InitialContextFactory; + +/** + * This is the context factory that creates the context used for looking up and invoking + * remote EJBs. + * + *

+ * Clients wanting to use remote EJB in this way should set the property in the initial context + * environment as follows: + * + *

+ * 
+ *   Hashtable<String, String> environment = new Hashtable<>();
+ *   environment.put(INITIAL_CONTEXT_FACTORY, "fish.payara.ejb.rest.client.RemoteEJBContextFactory");
+ *    ...
+ *   new InitialContext(environment);
+ * 
+ * 
+ * + * @author Arjan Tijms + * @since Payara 5.191 + */ +public class RemoteEJBContextFactory implements InitialContextFactory { + + public static final String FISH_PAYARA_WITH_CONFIG = "fish.payara.withConfig"; + public static final String FISH_PAYARA_TRUST_STORE = "fish.payara.trustStore"; + public static final String FISH_PAYARA_SSL_CONTEXT = "fish.payara.sslContext"; + public static final String FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE = "fish.payara.scheduledExecutorService"; + public static final String FISH_PAYARA_READ_TIMEOUT = "fish.payara.readTimeout"; + public static final String FISH_PAYARA_KEY_STORE = "fish.payara.keyStore"; + public static final String FISH_PAYARA_HOSTNAME_VERIFIER = "fish.payara.hostnameVerifier"; + public static final String FISH_PAYARA_EXECUTOR_SERVICE = "fish.payara.executorService"; + public static final String FISH_PAYARA_CONNECT_TIMEOUT = "fish.payara.connectTimeout"; + + @Override + public Context getInitialContext(Hashtable environment) throws NamingException { + return new RemoteEJBContext(environment); + } + +} diff --git a/appserver/ejb/ejb-http-remoting/endpoint/pom.xml b/appserver/ejb/ejb-http-remoting/endpoint/pom.xml new file mode 100644 index 00000000000..7aa4a287158 --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/endpoint/pom.xml @@ -0,0 +1,91 @@ + + + + + 4.0.0 + + + fish.payara.ejb.http + ejb-http-remoting + 5.192-SNAPSHOT + + + ejb-http-endpoint + war + + EJB - HTTP Endpoint + + This module contains the endpoint that services HTTP commands from the client (fish.payara.ejb.http:ejb-http-client) and looks EJBs up and invokes them. + + It contains a mini web application that is picked up by the domain template (org.glassfish.main.admin:nucleus-domain) which places it in the + glassfish/domains/[domainname]/endpoints/ejb-invoker folder. + + + + + javax.servlet + javax.servlet-api + provided + + + javax.json.bind + javax.json.bind-api + provided + + + javax.json + javax.json-api + provided + + + javax.ws.rs + javax.ws.rs-api + provided + + + org.glassfish.main.security + security-ee + ${project.version} + provided + + + + diff --git a/appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java b/appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java new file mode 100644 index 00000000000..f0c16d2906e --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java @@ -0,0 +1,215 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.ejb.invoke; + +import static javax.naming.Context.SECURITY_CREDENTIALS; +import static javax.naming.Context.SECURITY_PRINCIPAL; +import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +import java.io.IOException; +import java.util.Base64; +import java.util.List; +import java.util.function.Supplier; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonString; +import javax.json.JsonValue; +import javax.json.bind.JsonbBuilder; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.glassfish.internal.api.Globals; +import org.glassfish.internal.data.ApplicationRegistry; + +import com.sun.enterprise.security.ee.auth.login.ProgrammaticLogin; + +/** + */ +@WebServlet("/ejb/*") +public class InvokeEJBServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + response.getWriter().append("Served at: ").append(request.getContextPath()); + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + JsonObject requestPayload = + Json.createReader(request.getReader()) + .readObject(); + + if (request.getRequestURI().endsWith("lookup")) { + boolean success = excuteInAppContext(() -> { + + try { + response.getWriter().print( + new InitialContext().lookup(requestPayload.getString("lookup")) + .getClass() + .getInterfaces()[0] + .getName()); + return true; + } catch (IOException | NamingException e) { + // Ignore for now + } + + return false; + }); + + if (!success) { + response.sendError(SC_INTERNAL_SERVER_ERROR, "Name " + requestPayload.getString("lookup") + " not found when doing initial lookup"); + } + + return; + } + + // Convert JSON encoded method parameter type names to actually Class instances + Class[] argTypes = + requestPayload.getJsonArray("argTypes").stream() + .map(e -> toClass(e)) + .toArray(Class[]::new); + + // Convert JSON encoded method parameter values to their object instances + List jsonArgValues = requestPayload.getJsonArray("argValues"); + Object[] argValues = new Object[argTypes.length]; + for (int i = 0; i < jsonArgValues.size(); i++) { + argValues[i] = toObject(jsonArgValues.get(i), argTypes[i]); + } + + boolean success = excuteInAppContext(() -> { + try { + // Obtain the target EJB that we're going to invoke + Object bean = new InitialContext().lookup(requestPayload.getString("lookup")); + + // Authenticates the caller and if successful sets the security context + // *for the outgoing EJB call*. In other words, the security context for this + // Servlet will not be changed. + if (requestPayload.containsKey(SECURITY_PRINCIPAL)) { + ProgrammaticLogin login = new ProgrammaticLogin(); + login.login( + base64Decode(requestPayload.getString(SECURITY_PRINCIPAL)), + base64Decode(requestPayload.getString(SECURITY_CREDENTIALS)), + null, true); + } + + // Actually invoke the target EJB + Object result = + bean.getClass() + .getMethod(requestPayload.getString("method"), argTypes) + .invoke(bean, argValues); + + response.setContentType(APPLICATION_JSON); + response.getWriter().print(result instanceof String? result : JsonbBuilder.create().toJson(result)); + + return true; + + } catch (Exception e) { + e.printStackTrace(); + } + + return false; + }); + + if (!success) { + response.sendError(SC_INTERNAL_SERVER_ERROR, "Name " + requestPayload.getString("lookup") + " not found when invoking"); + } + } + + private Class toClass(JsonValue classNameValue) { + try { + String className = null; + if (classNameValue instanceof JsonString) { + className = ((JsonString) classNameValue).getString(); + } else { + className = classNameValue.toString().replace("\"", ""); + } + + return Class.forName(className); + } catch (ClassNotFoundException e) { + throw new IllegalStateException(e); + } + } + + private Object toObject(JsonValue objectValue, Class type) { + return JsonbBuilder + .create() + .fromJson(objectValue.toString(), type); + } + + private boolean excuteInAppContext(Supplier body) { + ApplicationRegistry registry = Globals.get(ApplicationRegistry.class); + + for (String applicationName : registry.getAllApplicationNames()) { + ClassLoader existingContextClassLoader = Thread.currentThread().getContextClassLoader(); + try { + + Thread.currentThread().setContextClassLoader(registry.get(applicationName).getAppClassLoader()); + + try { + if (body.get()) { + return true; + } + } catch (Exception e) { + // ignore + } + + } finally { + if (existingContextClassLoader != null) { + Thread.currentThread().setContextClassLoader(existingContextClassLoader); + } + } + + } + + return false; + } + + private static String base64Decode(String input) { + return new String(Base64.getDecoder().decode(input)); + } + +} diff --git a/appserver/ejb/ejb-http-remoting/pom.xml b/appserver/ejb/ejb-http-remoting/pom.xml new file mode 100755 index 00000000000..7f8c10c3bca --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/pom.xml @@ -0,0 +1,68 @@ + + + + 4.0.0 + + org.glassfish.main.ejb + ejb + 5.192-SNAPSHOT + + + fish.payara.ejb.http + ejb-http-remoting + pom + + EJB - HTTP + + + This module is the parent module for the lightweight HTTP-based EJB remote system. It contains an admin + module that has CLI (AsAdmin) commands for configuring the server side. An endpoint module that implements + the endpoint which receives the HTTP calls from the client and invoked an EJB, and finally a client module + which is used by the client to lookup and invoke EJB methods on a proxy. + + + + admin + endpoint + client + + + From 7472344adc24ee806345c0051f1af5127d930ed7 Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Thu, 7 Mar 2019 16:59:24 +0000 Subject: [PATCH 008/108] Updated class packages to http --- .../admin/DisableEjbInvokerCommand.java | 2 +- .../admin/EnableEjbInvokerCommand.java | 2 +- .../ejb/ejb-http-remoting/client/pom.xml | 2 +- .../client/EjbRestProxyFactory.java | 2 +- .../client/EjbRestProxyHandler.java | 2 +- .../client/RemoteEJBContext.java | 22 +++++++++---------- .../client/RemoteEJBContextFactory.java | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) rename appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/{rest => http}/admin/DisableEjbInvokerCommand.java (99%) rename appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/{rest => http}/admin/EnableEjbInvokerCommand.java (99%) rename appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/{rest => http}/client/EjbRestProxyFactory.java (99%) rename appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/{rest => http}/client/EjbRestProxyHandler.java (99%) rename appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/{rest => http}/client/RemoteEJBContext.java (95%) rename appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/{rest => http}/client/RemoteEJBContextFactory.java (99%) diff --git a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/http/admin/DisableEjbInvokerCommand.java similarity index 99% rename from appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java rename to appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/http/admin/DisableEjbInvokerCommand.java index 9d26352ab71..71a1790887b 100644 --- a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java +++ b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/http/admin/DisableEjbInvokerCommand.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -package fish.payara.ejb.rest.admin; +package fish.payara.ejb.http.admin; import static org.glassfish.config.support.CommandTarget.CLUSTER; import static org.glassfish.config.support.CommandTarget.CLUSTERED_INSTANCE; diff --git a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/http/admin/EnableEjbInvokerCommand.java similarity index 99% rename from appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java rename to appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/http/admin/EnableEjbInvokerCommand.java index 99c35c0bfa3..b6147212cec 100644 --- a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java +++ b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/http/admin/EnableEjbInvokerCommand.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -package fish.payara.ejb.rest.admin; +package fish.payara.ejb.http.admin; import static org.glassfish.config.support.CommandTarget.CLUSTER; import static org.glassfish.config.support.CommandTarget.CLUSTERED_INSTANCE; diff --git a/appserver/ejb/ejb-http-remoting/client/pom.xml b/appserver/ejb/ejb-http-remoting/client/pom.xml index e52190577b9..d1d625a8aef 100644 --- a/appserver/ejb/ejb-http-remoting/client/pom.xml +++ b/appserver/ejb/ejb-http-remoting/client/pom.xml @@ -43,7 +43,7 @@ fish.payara.ejb.http - ejb-rest-remoting + ejb-http-remoting 5.192-SNAPSHOT diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyFactory.java similarity index 99% rename from appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java rename to appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyFactory.java index 58592bd0339..bfe40f8c287 100644 --- a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyFactory.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -package fish.payara.ejb.rest.client; +package fish.payara.ejb.http.client; import static java.lang.reflect.Proxy.newProxyInstance; import static java.security.AccessController.doPrivileged; diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyHandler.java similarity index 99% rename from appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java rename to appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyHandler.java index 23c5f67d719..7aa0576d09e 100644 --- a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyHandler.java @@ -1,4 +1,4 @@ -package fish.payara.ejb.rest.client; +package fish.payara.ejb.http.client; import static javax.naming.Context.SECURITY_CREDENTIALS; import static javax.naming.Context.SECURITY_PRINCIPAL; diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/RemoteEJBContext.java similarity index 95% rename from appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java rename to appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/RemoteEJBContext.java index f961a081252..f3801433bb0 100644 --- a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/RemoteEJBContext.java @@ -37,17 +37,17 @@ * only if the new code is made subject to such option by the copyright * holder. */ -package fish.payara.ejb.rest.client; - -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_CONNECT_TIMEOUT; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_EXECUTOR_SERVICE; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_HOSTNAME_VERIFIER; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_KEY_STORE; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_READ_TIMEOUT; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_SSL_CONTEXT; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_TRUST_STORE; -import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_WITH_CONFIG; +package fish.payara.ejb.http.client; + +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_CONNECT_TIMEOUT; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_EXECUTOR_SERVICE; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_HOSTNAME_VERIFIER; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_KEY_STORE; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_READ_TIMEOUT; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_SSL_CONTEXT; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_TRUST_STORE; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_WITH_CONFIG; import static java.util.concurrent.TimeUnit.MICROSECONDS; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/RemoteEJBContextFactory.java similarity index 99% rename from appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java rename to appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/RemoteEJBContextFactory.java index ed0518333dd..d8959063fab 100644 --- a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/RemoteEJBContextFactory.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -package fish.payara.ejb.rest.client; +package fish.payara.ejb.http.client; import java.util.Hashtable; From f576f2f4cf2fbb442bec8b73589ce36557a17b81 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Fri, 8 Mar 2019 17:58:10 +0100 Subject: [PATCH 009/108] PAYARA-3466 Open API 1.1 implemented new methods, removed builder with defaults, removed warnings, extracted common base classes for extensible maps, switched to non-deprecated methods --- .../openapi/api/visitor/ApiVisitor.java | 1 - .../openapi/impl/OpenApiService.java | 13 +- .../admin/OpenApiServiceConfiguration.java | 3 +- .../impl/config/OpenApiConfiguration.java | 12 +- .../openapi/impl/model/ComponentsImpl.java | 83 +++--- .../openapi/impl/model/ExtensibleImpl.java | 13 +- .../impl/model/ExtensibleLinkedHashMap.java | 43 +++ .../impl/model/ExternalDocumentationImpl.java | 14 +- .../openapi/impl/model/OpenAPIImpl.java | 61 +---- .../openapi/impl/model/OperationImpl.java | 83 ++---- .../openapi/impl/model/PathItemImpl.java | 94 ++----- .../openapi/impl/model/PathsImpl.java | 31 ++- .../impl/model/callbacks/CallbackImpl.java | 49 ++-- .../impl/model/examples/ExampleImpl.java | 32 +-- .../impl/model/headers/HeaderImpl.java | 71 +---- .../openapi/impl/model/info/ContactImpl.java | 20 +- .../openapi/impl/model/info/InfoImpl.java | 38 +-- .../openapi/impl/model/info/LicenseImpl.java | 14 +- .../openapi/impl/model/links/LinkImpl.java | 47 +--- .../openapi/impl/model/media/ContentImpl.java | 30 ++- .../impl/model/media/DiscriminatorImpl.java | 16 +- .../impl/model/media/EncodingImpl.java | 35 +-- .../impl/model/media/MediaTypeImpl.java | 32 +-- .../openapi/impl/model/media/SchemaImpl.java | 254 +++--------------- .../openapi/impl/model/media/XMLImpl.java | 32 +-- .../impl/model/parameters/ParameterImpl.java | 89 +----- .../model/parameters/RequestBodyImpl.java | 26 +- .../impl/model/responses/APIResponseImpl.java | 38 +-- .../model/responses/APIResponsesImpl.java | 49 +++- .../impl/model/security/OAuthFlowImpl.java | 26 +- .../impl/model/security/OAuthFlowsImpl.java | 26 +- .../impl/model/security/ScopesImpl.java | 27 +- .../security/SecurityRequirementImpl.java | 25 ++ .../model/security/SecuritySchemeImpl.java | 56 +--- .../impl/model/servers/ServerImpl.java | 29 +- .../model/servers/ServerVariableImpl.java | 25 +- .../model/servers/ServerVariablesImpl.java | 29 +- .../openapi/impl/model/tags/TagImpl.java | 20 +- .../openapi/impl/model/util/ModelUtils.java | 24 +- .../impl/processor/ApplicationProcessor.java | 65 +++-- .../openapi/impl/processor/BaseProcessor.java | 24 +- .../impl/processor/FilterProcessor.java | 5 +- .../impl/processor/ModelReaderProcessor.java | 3 +- .../classloader/ApplicationClassLoader.java | 8 +- .../test/app/application/ResponseTest.java | 14 +- .../test/app/application/RootPathTest.java | 4 +- appserver/pom.xml | 2 +- 47 files changed, 515 insertions(+), 1220 deletions(-) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleLinkedHashMap.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiVisitor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiVisitor.java index eb0bccf2ddf..9b68002576e 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiVisitor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiVisitor.java @@ -41,7 +41,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Field; import java.lang.reflect.Method; import javax.ws.rs.Consumes; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/OpenApiService.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/OpenApiService.java index f8dbce05780..28064b5e173 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/OpenApiService.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/OpenApiService.java @@ -49,7 +49,6 @@ import fish.payara.microprofile.openapi.impl.processor.FileProcessor; import fish.payara.microprofile.openapi.impl.processor.FilterProcessor; import fish.payara.microprofile.openapi.impl.processor.ModelReaderProcessor; -import fish.payara.nucleus.executorservice.PayaraExecutorService; import java.beans.PropertyChangeEvent; import java.net.InetAddress; import java.net.MalformedURLException; @@ -58,7 +57,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Deque; -import java.util.Enumeration; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentLinkedDeque; @@ -105,9 +103,6 @@ public class OpenApiService implements PostConstruct, PreDestroy, EventListener, @Inject private OpenApiServiceConfiguration config; - @Inject - private PayaraExecutorService executor; - @Inject private ServerEnvironment environment; @@ -189,7 +184,7 @@ public OpenAPI getDocument() throws OpenAPIBuildException { if (mappings.isEmpty() || !isEnabled()) { return null; } - return (OpenAPI) mappings.peekLast().getDocument(); + return mappings.peekLast().getDocument(); } /** @@ -224,7 +219,7 @@ private static String getContextRoot(ApplicationInfo appInfo) { * @return a list of all loadable classes in the archive. */ private static Set> getClassesFromArchive(ReadableArchive archive, ClassLoader appClassLoader) { - return Collections.list((Enumeration) archive.entries()).stream() + return Collections.list(archive.entries()).stream() // Only use the classes .filter(x -> x.endsWith(".class")) // Remove the WEB-INF/classes and return the proper class name format @@ -262,12 +257,12 @@ private class OpenApiMapping { private final OpenApiConfiguration appConfig; private volatile OpenAPI document; - private OpenApiMapping(ApplicationInfo appInfo) { + OpenApiMapping(ApplicationInfo appInfo) { this.appInfo = appInfo; this.appConfig = new OpenApiConfiguration(appInfo.getAppClassLoader()); } - private ApplicationInfo getAppInfo() { + ApplicationInfo getAppInfo() { return appInfo; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/admin/OpenApiServiceConfiguration.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/admin/OpenApiServiceConfiguration.java index ba7eb07e9b7..9858b0561fc 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/admin/OpenApiServiceConfiguration.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/admin/OpenApiServiceConfiguration.java @@ -42,14 +42,13 @@ import java.beans.PropertyVetoException; import org.glassfish.api.admin.config.ConfigExtension; import org.jvnet.hk2.config.Attribute; -import org.jvnet.hk2.config.ConfigBeanProxy; import org.jvnet.hk2.config.Configured; /** * Configuration for the OpenAPI Service. */ @Configured(name = "microprofile-openapi-configuration") -public interface OpenApiServiceConfiguration extends ConfigBeanProxy, ConfigExtension { +public interface OpenApiServiceConfiguration extends ConfigExtension { /** * @return whether the service is enabled or not. diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/config/OpenApiConfiguration.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/config/OpenApiConfiguration.java index fb104683f8b..7ada410d15a 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/config/OpenApiConfiguration.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/config/OpenApiConfiguration.java @@ -224,7 +224,7 @@ private Class findFilterFromConfig(Config config, ClassLoad return null; } - private boolean findScanDisableFromConfig(Config config) { + private static boolean findScanDisableFromConfig(Config config) { try { return config.getValue(SCAN_DISABLE_KEY, Boolean.class); } catch (NoSuchElementException ex) { @@ -233,7 +233,7 @@ private boolean findScanDisableFromConfig(Config config) { return false; } - private List findScanPackagesFromConfig(Config config) { + private static List findScanPackagesFromConfig(Config config) { List packages = new ArrayList<>(); try { packages.addAll(Arrays.asList(config.getValue(SCAN_PACKAGES_KEY, String[].class))); @@ -259,7 +259,7 @@ private List> findScanClassesFromConfig(Config config, ClassLoader clas return classes; } - private List findExcludePackages(Config config) { + private static List findExcludePackages(Config config) { List packages = new ArrayList<>(); try { packages.addAll(Arrays.asList(config.getValue(SCAN_EXCLUDE_PACKAGES_KEY, String[].class))); @@ -285,7 +285,7 @@ private List> findExcludeClasses(Config config, ClassLoader classLoader return classes; } - private List findServers(Config config) { + private static List findServers(Config config) { List serverList = new ArrayList<>(); try { serverList.addAll(Arrays.asList(config.getValue(SERVERS_KEY, String[].class))); @@ -295,7 +295,7 @@ private List findServers(Config config) { return serverList; } - private Map> findPathServerMap(Config config) { + private static Map> findPathServerMap(Config config) { Map> map = new HashMap<>(); try { for (String propertyName : config.getPropertyNames()) { @@ -310,7 +310,7 @@ private Map> findPathServerMap(Config config) { return map; } - private Map> findOperationServerMap(Config config) { + private static Map> findOperationServerMap(Config config) { Map> map = new HashMap<>(); try { for (String propertyName : config.getPropertyNames()) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ComponentsImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ComponentsImpl.java index 95f05cf6068..51613fdd642 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ComponentsImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ComponentsImpl.java @@ -64,7 +64,7 @@ import fish.payara.microprofile.openapi.impl.model.responses.APIResponseImpl; import fish.payara.microprofile.openapi.impl.model.security.SecuritySchemeImpl; -public class ComponentsImpl extends ExtensibleImpl implements Components { +public class ComponentsImpl extends ExtensibleImpl implements Components { protected Map schemas = new TreeMap<>(); protected Map responses = new TreeMap<>(); @@ -87,15 +87,14 @@ public void setSchemas(Map schemas) { } @Override - public Components schemas(Map schemas) { - setSchemas(schemas); + public Components addSchema(String key, Schema schema) { + schemas.put(key, schema); return this; } @Override - public Components addSchema(String key, Schema schema) { - schemas.put(key, schema); - return this; + public void removeSchema(String key) { + schemas.remove(key); } @Override @@ -109,15 +108,14 @@ public void setResponses(Map responses) { } @Override - public Components responses(Map responses) { - setResponses(responses); + public Components addResponse(String key, APIResponse response) { + responses.put(key, response); return this; } @Override - public Components addResponse(String key, APIResponse response) { - responses.put(key, response); - return this; + public void removeResponse(String key) { + responses.remove(key); } @Override @@ -131,15 +129,14 @@ public void setParameters(Map parameters) { } @Override - public Components parameters(Map parameters) { - setParameters(parameters); + public Components addParameter(String key, Parameter parameter) { + parameters.put(key, parameter); return this; } @Override - public Components addParameter(String key, Parameter parameter) { - parameters.put(key, parameter); - return this; + public void removeParameter(String key) { + parameters.remove(key); } @Override @@ -153,15 +150,14 @@ public void setExamples(Map examples) { } @Override - public Components examples(Map examples) { - setExamples(examples); + public Components addExample(String key, Example example) { + examples.put(key, example); return this; } @Override - public Components addExample(String key, Example example) { - examples.put(key, example); - return this; + public void removeExample(String key) { + examples.remove(key); } @Override @@ -175,15 +171,14 @@ public void setRequestBodies(Map requestBodies) { } @Override - public Components requestBodies(Map requestBodies) { - setRequestBodies(requestBodies); + public Components addRequestBody(String key, RequestBody requestBody) { + requestBodies.put(key, requestBody); return this; } @Override - public Components addRequestBody(String key, RequestBody requestBody) { - requestBodies.put(key, requestBody); - return this; + public void removeRequestBody(String key) { + requestBodies.remove(key); } @Override @@ -197,15 +192,14 @@ public void setHeaders(Map headers) { } @Override - public Components headers(Map headers) { - setHeaders(headers); + public Components addHeader(String key, Header header) { + headers.put(key, header); return this; } @Override - public Components addHeader(String key, Header header) { - headers.put(key, header); - return this; + public void removeHeader(String key) { + headers.remove(key); } @Override @@ -219,15 +213,14 @@ public void setSecuritySchemes(Map securitySchemes) { } @Override - public Components securitySchemes(Map securitySchemes) { - setSecuritySchemes(securitySchemes); + public Components addSecurityScheme(String key, SecurityScheme securityScheme) { + securitySchemes.put(key, securityScheme); return this; } @Override - public Components addSecurityScheme(String key, SecurityScheme securityScheme) { - securitySchemes.put(key, securityScheme); - return this; + public void removeSecurityScheme(String key) { + securitySchemes.remove(key); } @Override @@ -241,15 +234,14 @@ public void setLinks(Map links) { } @Override - public Components links(Map links) { - setLinks(links); + public Components addLink(String key, Link link) { + links.put(key, link); return this; } @Override - public Components addLink(String key, Link link) { - links.put(key, link); - return this; + public void removeLink(String key) { + links.remove(key); } @Override @@ -263,15 +255,14 @@ public void setCallbacks(Map callbacks) { } @Override - public Components callbacks(Map callbacks) { - setCallbacks(callbacks); + public Components addCallback(String key, Callback callback) { + callbacks.put(key, callback); return this; } @Override - public Components addCallback(String key, Callback callback) { - callbacks.put(key, callback); - return this; + public void removeCallback(String key) { + callbacks.remove(key); } public static void merge(org.eclipse.microprofile.openapi.annotations.Components from, Components to, diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index 96555b12abd..6c6db641ffa 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -49,7 +49,7 @@ import org.eclipse.microprofile.openapi.annotations.extensions.Extension; import org.eclipse.microprofile.openapi.models.Extensible; -public abstract class ExtensibleImpl implements Extensible { +public abstract class ExtensibleImpl> implements Extensible { protected Map extensions = new HashMap<>(); @@ -58,9 +58,16 @@ public Map getExtensions() { return extensions; } + @SuppressWarnings("unchecked") @Override - public void addExtension(String name, Object value) { + public T addExtension(String name, Object value) { extensions.put(name, value); + return (T) this; + } + + @Override + public void removeExtension(String name) { + extensions.remove(name); } @Override @@ -68,7 +75,7 @@ public void setExtensions(Map extensions) { this.extensions = extensions; } - public static void merge(Extension from, Extensible to, boolean override) { + public static void merge(Extension from, Extensible to, boolean override) { if (isAnnotationNull(from)) { return; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleLinkedHashMap.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleLinkedHashMap.java new file mode 100644 index 00000000000..477307e6d5d --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleLinkedHashMap.java @@ -0,0 +1,43 @@ +package fish.payara.microprofile.openapi.impl.model; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.microprofile.openapi.models.Extensible; + +public abstract class ExtensibleLinkedHashMap> extends LinkedHashMap +implements Extensible { + + protected Map extensions = new HashMap<>(); + + protected ExtensibleLinkedHashMap() { + super(); + } + + protected ExtensibleLinkedHashMap(Map items) { + super(items); + } + + @Override + public final Map getExtensions() { + return extensions; + } + + @Override + public final void setExtensions(Map extensions) { + this.extensions = extensions; + } + + @SuppressWarnings("unchecked") + @Override + public final T addExtension(String name, Object value) { + this.extensions.put(name, value); + return (T) this; + } + + @Override + public final void removeExtension(String name) { + this.extensions.remove(name); + } +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExternalDocumentationImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExternalDocumentationImpl.java index ae7b6aa08bf..4812fd6591e 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExternalDocumentationImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExternalDocumentationImpl.java @@ -44,7 +44,7 @@ import org.eclipse.microprofile.openapi.models.ExternalDocumentation; -public class ExternalDocumentationImpl extends ExtensibleImpl implements ExternalDocumentation { +public class ExternalDocumentationImpl extends ExtensibleImpl implements ExternalDocumentation { protected String description; protected String url; @@ -59,12 +59,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public ExternalDocumentation description(String description) { - setDescription(description); - return this; - } - @Override public String getUrl() { return url; @@ -75,12 +69,6 @@ public void setUrl(String url) { this.url = url; } - @Override - public ExternalDocumentation url(String url) { - setUrl(url); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.ExternalDocumentation from, ExternalDocumentation to, boolean override) { if (isAnnotationNull(from)) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OpenAPIImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OpenAPIImpl.java index 371eba7b123..4697a22f492 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OpenAPIImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OpenAPIImpl.java @@ -61,7 +61,7 @@ import fish.payara.microprofile.openapi.impl.model.tags.TagImpl; import fish.payara.microprofile.openapi.impl.model.util.ModelUtils; -public class OpenAPIImpl extends ExtensibleImpl implements OpenAPI { +public class OpenAPIImpl extends ExtensibleImpl implements OpenAPI { protected String openapi; protected Info info; @@ -82,12 +82,6 @@ public void setOpenapi(String openapi) { this.openapi = openapi; } - @Override - public OpenAPI openapi(String openapi) { - setOpenapi(openapi); - return this; - } - @Override public Info getInfo() { return info; @@ -98,12 +92,6 @@ public void setInfo(Info info) { this.info = info; } - @Override - public OpenAPI info(Info info) { - setInfo(info); - return this; - } - @Override public ExternalDocumentation getExternalDocs() { return externalDocs; @@ -114,12 +102,6 @@ public void setExternalDocs(ExternalDocumentation externalDocs) { this.externalDocs = externalDocs; } - @Override - public OpenAPI externalDocs(ExternalDocumentation externalDocs) { - setExternalDocs(externalDocs); - return this; - } - @Override public List getServers() { return servers; @@ -130,12 +112,6 @@ public void setServers(List servers) { this.servers = servers; } - @Override - public OpenAPI servers(List servers) { - setServers(servers); - return this; - } - @Override public OpenAPI addServer(Server server) { if (server.getUrl() != null) { @@ -153,6 +129,11 @@ public OpenAPI addServer(Server server) { return this; } + @Override + public void removeServer(Server server) { + servers.remove(server); + } + @Override public List getSecurity() { return security; @@ -164,15 +145,14 @@ public void setSecurity(List security) { } @Override - public OpenAPI security(List security) { - setSecurity(security); + public OpenAPI addSecurityRequirement(SecurityRequirement securityRequirement) { + security.add(securityRequirement); return this; } @Override - public OpenAPI addSecurityRequirement(SecurityRequirement securityRequirement) { - security.add(securityRequirement); - return this; + public void removeSecurityRequirement(SecurityRequirement securityRequirement) { + security.remove(securityRequirement); } @Override @@ -186,15 +166,14 @@ public void setTags(List tags) { } @Override - public OpenAPI tags(List tags) { - setTags(tags); + public OpenAPI addTag(Tag tag) { + tags.add(tag); return this; } @Override - public OpenAPI addTag(Tag tag) { - tags.add(tag); - return this; + public void removeTag(Tag tag) { + tags.remove(tag); } @Override @@ -207,12 +186,6 @@ public void setPaths(Paths paths) { this.paths = paths; } - @Override - public OpenAPI paths(Paths paths) { - setPaths(paths); - return this; - } - @Override public OpenAPI path(String name, PathItem path) { paths.addPathItem(name, path); @@ -229,12 +202,6 @@ public void setComponents(Components components) { this.components = components; } - @Override - public OpenAPI components(Components components) { - setComponents(components); - return this; - } - public static void merge(OpenAPIDefinition from, OpenAPI to, boolean override) { if (isAnnotationNull(from)) { return; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OperationImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OperationImpl.java index 72e1abd0067..10d1940ac2c 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OperationImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OperationImpl.java @@ -64,7 +64,7 @@ import fish.payara.microprofile.openapi.impl.model.parameters.RequestBodyImpl; import fish.payara.microprofile.openapi.impl.model.responses.APIResponsesImpl; -public class OperationImpl extends ExtensibleImpl implements Operation { +public class OperationImpl extends ExtensibleImpl implements Operation { protected List tags = new ArrayList<>(); protected String summary; @@ -90,15 +90,14 @@ public void setTags(List tags) { } @Override - public Operation tags(List tags) { - setTags(tags); + public Operation addTag(String tag) { + tags.add(tag); return this; } @Override - public Operation addTag(String tag) { - tags.add(tag); - return this; + public void removeTag(String tag) { + tags.remove(tag); } @Override @@ -111,12 +110,6 @@ public void setSummary(String summary) { this.summary = summary; } - @Override - public Operation summary(String summary) { - setSummary(summary); - return this; - } - @Override public String getDescription() { return description; @@ -127,12 +120,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public Operation description(String description) { - setDescription(description); - return this; - } - @Override public ExternalDocumentation getExternalDocs() { return externalDocs; @@ -143,12 +130,6 @@ public void setExternalDocs(ExternalDocumentation externalDocs) { this.externalDocs = externalDocs; } - @Override - public Operation externalDocs(ExternalDocumentation externalDocs) { - setExternalDocs(externalDocs); - return this; - } - @Override public String getOperationId() { return operationId; @@ -159,12 +140,6 @@ public void setOperationId(String operationId) { this.operationId = operationId; } - @Override - public Operation operationId(String operationId) { - setOperationId(operationId); - return this; - } - @Override public List getParameters() { return parameters; @@ -176,15 +151,14 @@ public void setParameters(List parameters) { } @Override - public Operation parameters(List parameters) { - setParameters(parameters); + public Operation addParameter(Parameter parameter) { + parameters.add(parameter); return this; } @Override - public Operation addParameter(Parameter parameter) { - parameters.add(parameter); - return this; + public void removeParameter(Parameter parameter) { + parameters.remove(parameter); } @Override @@ -197,12 +171,6 @@ public void setRequestBody(RequestBody requestBody) { this.requestBody = requestBody; } - @Override - public Operation requestBody(RequestBody requestBody) { - setRequestBody(requestBody); - return this; - } - @Override public APIResponses getResponses() { return responses; @@ -213,12 +181,6 @@ public void setResponses(APIResponses responses) { this.responses = responses; } - @Override - public Operation responses(APIResponses responses) { - setResponses(responses); - return this; - } - @Override public Map getCallbacks() { return callbacks; @@ -230,11 +192,16 @@ public void setCallbacks(Map callbacks) { } @Override - public Operation callbacks(Map callbacks) { - setCallbacks(callbacks); + public Operation addCallback(String key, Callback callback) { + this.callbacks.put(key, callback); return this; } + @Override + public void removeCallback(String key) { + this.callbacks.remove(key); + } + @Override public Boolean getDeprecated() { return deprecated; @@ -262,15 +229,14 @@ public void setSecurity(List security) { } @Override - public Operation security(List security) { - setSecurity(security); + public Operation addSecurityRequirement(SecurityRequirement securityReq) { + security.add(securityReq); return this; } @Override - public Operation addSecurityRequirement(SecurityRequirement securityReq) { - security.add(securityReq); - return this; + public void removeSecurityRequirement(SecurityRequirement securityRequirement) { + security.remove(securityRequirement); } @Override @@ -284,15 +250,14 @@ public void setServers(List servers) { } @Override - public Operation servers(List servers) { - setServers(servers); + public Operation addServer(Server server) { + servers.add(server); return this; } @Override - public Operation addServer(Server server) { - servers.add(server); - return this; + public void removeServer(Server server) { + servers.remove(server); } public static void merge(org.eclipse.microprofile.openapi.annotations.Operation from, Operation to, diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java index e37eeaf54f6..e06c2e7fb3a 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java @@ -50,7 +50,7 @@ import org.eclipse.microprofile.openapi.models.parameters.Parameter; import org.eclipse.microprofile.openapi.models.servers.Server; -public class PathItemImpl extends ExtensibleImpl implements PathItem { +public class PathItemImpl extends ExtensibleImpl implements PathItem { protected String ref; protected String summary; @@ -76,12 +76,6 @@ public void setRef(String ref) { this.ref = ref; } - @Override - public PathItem ref(String ref) { - setRef(ref); - return this; - } - @Override public String getSummary() { return summary; @@ -92,12 +86,6 @@ public void setSummary(String summary) { this.summary = summary; } - @Override - public PathItem summary(String summary) { - setSummary(summary); - return this; - } - @Override public String getDescription() { return description; @@ -108,12 +96,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public PathItem description(String description) { - setDescription(description); - return this; - } - @Override public Operation getGET() { return get; @@ -124,12 +106,6 @@ public void setGET(Operation get) { this.get = get; } - @Override - public PathItem GET(Operation get) { - setGET(get); - return this; - } - @Override public Operation getPUT() { return put; @@ -140,12 +116,6 @@ public void setPUT(Operation put) { this.put = put; } - @Override - public PathItem PUT(Operation put) { - setPUT(put); - return this; - } - @Override public Operation getPOST() { return post; @@ -156,12 +126,6 @@ public void setPOST(Operation post) { this.post = post; } - @Override - public PathItem POST(Operation post) { - setPOST(post); - return this; - } - @Override public Operation getDELETE() { return delete; @@ -172,12 +136,6 @@ public void setDELETE(Operation delete) { this.delete = delete; } - @Override - public PathItem DELETE(Operation delete) { - setDELETE(delete); - return this; - } - @Override public Operation getOPTIONS() { return options; @@ -188,12 +146,6 @@ public void setOPTIONS(Operation options) { this.options = options; } - @Override - public PathItem OPTIONS(Operation options) { - setOPTIONS(options); - return this; - } - @Override public Operation getHEAD() { return head; @@ -204,12 +156,6 @@ public void setHEAD(Operation head) { this.head = head; } - @Override - public PathItem HEAD(Operation head) { - setHEAD(head); - return this; - } - @Override public Operation getPATCH() { return patch; @@ -220,12 +166,6 @@ public void setPATCH(Operation patch) { this.patch = patch; } - @Override - public PathItem PATCH(Operation patch) { - setPATCH(patch); - return this; - } - @Override public Operation getTRACE() { return trace; @@ -237,9 +177,17 @@ public void setTRACE(Operation trace) { } @Override - public PathItem TRACE(Operation trace) { - setTRACE(trace); - return this; + public Map getOperations() { + EnumMap operations = new EnumMap<>(HttpMethod.class); + operations.put(HttpMethod.DELETE, delete); + operations.put(HttpMethod.GET, get); + operations.put(HttpMethod.HEAD, head); + operations.put(HttpMethod.OPTIONS, options); + operations.put(HttpMethod.PATCH, patch); + operations.put(HttpMethod.POST, post); + operations.put(HttpMethod.PUT, put); + operations.put(HttpMethod.TRACE, trace); + return operations; } @Override @@ -316,15 +264,14 @@ public void setServers(List servers) { } @Override - public PathItem servers(List servers) { - setServers(servers); + public PathItem addServer(Server server) { + servers.add(server); return this; } @Override - public PathItem addServer(Server server) { - servers.add(server); - return this; + public void removeServer(Server server) { + servers.remove(server); } @Override @@ -338,15 +285,14 @@ public void setParameters(List parameters) { } @Override - public PathItem parameters(List parameters) { - setParameters(parameters); + public PathItem addParameter(Parameter parameter) { + parameters.add(parameter); return this; } @Override - public PathItem addParameter(Parameter parameter) { - parameters.add(parameter); - return this; + public void removeParameter(Parameter parameter) { + parameters.remove(parameter); } @Override diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java index fb6b666a2aa..e49c65435b7 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java @@ -39,40 +39,45 @@ */ package fish.payara.microprofile.openapi.impl.model; -import java.util.HashMap; import java.util.Map; -import java.util.TreeMap; import org.eclipse.microprofile.openapi.models.PathItem; import org.eclipse.microprofile.openapi.models.Paths; import fish.payara.microprofile.openapi.impl.model.util.ModelUtils; -public class PathsImpl extends TreeMap implements Paths { +public class PathsImpl extends ExtensibleLinkedHashMap implements Paths { private static final long serialVersionUID = -3876996963579977405L; - protected Map extensions = new HashMap<>(); + public PathsImpl() { + super(); + } + + public PathsImpl(Map items) { + super(items); + } @Override public Paths addPathItem(String name, PathItem item) { - super.put(name, item); + put(name, item); return this; } @Override - public Map getExtensions() { - return extensions; + public void removePathItem(String name) { + remove(name); } @Override - public void addExtension(String name, Object value) { - extensions.put(name, value); + public Map getPathItems() { + return new PathsImpl(this); } @Override - public void setExtensions(Map extensions) { - this.extensions = extensions; + public void setPathItems(Map items) { + clear(); + putAll(items); } public static void merge(Paths from, Paths to, boolean override) { @@ -80,10 +85,10 @@ public static void merge(Paths from, Paths to, boolean override) { return; } from.entrySet().forEach(entry -> { - if (!to.containsKey(entry.getKey())) { + if (!to.hasPathItem(entry.getKey())) { to.addPathItem(entry.getKey(), entry.getValue()); } else { - ModelUtils.merge(entry.getValue(), to.get(entry.getKey()), override); + ModelUtils.merge(entry.getValue(), to.getPathItem(entry.getKey()), override); } }); } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java index a38e6313b7f..93bc3e8f437 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java @@ -44,8 +44,6 @@ import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.getOrCreateOperation; import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.isAnnotationNull; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.microprofile.openapi.annotations.callbacks.CallbackOperation; @@ -55,15 +53,23 @@ import org.eclipse.microprofile.openapi.models.callbacks.Callback; import org.eclipse.microprofile.openapi.models.media.Schema; +import fish.payara.microprofile.openapi.impl.model.ExtensibleLinkedHashMap; import fish.payara.microprofile.openapi.impl.model.OperationImpl; import fish.payara.microprofile.openapi.impl.model.PathItemImpl; -public class CallbackImpl extends LinkedHashMap implements Callback { +public class CallbackImpl extends ExtensibleLinkedHashMap implements Callback { private static final long serialVersionUID = 5549098533131353142L; protected String ref; - protected Map extensions = new HashMap<>(); + + public CallbackImpl() { + super(); + } + + public CallbackImpl(Map items) { + super(items); + } @Override public Callback addPathItem(String name, PathItem item) { @@ -72,37 +78,32 @@ public Callback addPathItem(String name, PathItem item) { } @Override - public String getRef() { - return this.ref; - } - - @Override - public void setRef(String ref) { - if (ref != null && !ref.contains(".") && !ref.contains("/")) { - ref = "#/components/callbacks/" + ref; - } - this.ref = ref; + public void removePathItem(String name) { + remove(name); } @Override - public Callback ref(String ref) { - setRef(ref); - return this; + public Map getPathItems() { + return new CallbackImpl(this); } @Override - public Map getExtensions() { - return extensions; + public void setPathItems(Map items) { + clear(); + putAll(items); } @Override - public void setExtensions(Map extensions) { - this.extensions = extensions; + public String getRef() { + return this.ref; } @Override - public void addExtension(String name, Object value) { - this.extensions.put(name, value); + public void setRef(String ref) { + if (ref != null && !ref.contains(".") && !ref.contains("/")) { + ref = "#/components/callbacks/" + ref; + } + this.ref = ref; } public static void merge(org.eclipse.microprofile.openapi.annotations.callbacks.Callback from, Callback to, @@ -116,7 +117,7 @@ public static void merge(org.eclipse.microprofile.openapi.annotations.callbacks. } if (!from.callbackUrlExpression().isEmpty()) { PathItem pathItem = to.getOrDefault(from.callbackUrlExpression(), new PathItemImpl()); - to.put(from.callbackUrlExpression(), pathItem); + to.addPathItem(from.callbackUrlExpression(), pathItem); if (from.operations() != null) { for (CallbackOperation callbackOperation : from.operations()) { applyCallbackOperationAnnotation(pathItem, callbackOperation, override, currentSchemas); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/examples/ExampleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/examples/ExampleImpl.java index b042d9577de..9c9174ed90c 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/examples/ExampleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/examples/ExampleImpl.java @@ -50,7 +50,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class ExampleImpl extends ExtensibleImpl implements Example { +public class ExampleImpl extends ExtensibleImpl implements Example { protected String summary; protected String description; @@ -68,12 +68,6 @@ public void setSummary(String summary) { this.summary = summary; } - @Override - public Example summary(String summary) { - setSummary(summary); - return this; - } - @Override public String getDescription() { return description; @@ -84,12 +78,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public Example description(String description) { - setDescription(description); - return this; - } - @Override public Object getValue() { return value; @@ -100,12 +88,6 @@ public void setValue(Object value) { this.value = value; } - @Override - public Example value(Object value) { - setValue(value); - return this; - } - @Override public String getExternalValue() { return externalValue; @@ -116,12 +98,6 @@ public void setExternalValue(String externalValue) { this.externalValue = externalValue; } - @Override - public Example externalValue(String externalValue) { - setExternalValue(externalValue); - return this; - } - @Override public String getRef() { return ref; @@ -135,12 +111,6 @@ public void setRef(String ref) { this.ref = ref; } - @Override - public Example ref(String ref) { - setRef(ref); - return this; - } - public static void merge(ExampleObject from, Example to, boolean override) { if (isAnnotationNull(from)) { return; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java index 469f19aade1..61aff64a342 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java @@ -55,7 +55,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; import fish.payara.microprofile.openapi.impl.model.media.SchemaImpl; -public class HeaderImpl extends ExtensibleImpl implements Header { +public class HeaderImpl extends ExtensibleImpl
implements Header { protected String ref; protected String description; @@ -82,12 +82,6 @@ public void setRef(String ref) { this.ref = ref; } - @Override - public Header ref(String ref) { - setRef(ref); - return this; - } - @Override public String getDescription() { return description; @@ -98,12 +92,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public Header description(String description) { - setDescription(description); - return this; - } - @Override public Boolean getRequired() { return required; @@ -114,12 +102,6 @@ public void setRequired(Boolean required) { this.required = required; } - @Override - public Header required(Boolean required) { - setRequired(required); - return this; - } - @Override public Boolean getDeprecated() { return deprecated; @@ -130,12 +112,6 @@ public void setDeprecated(Boolean deprecated) { this.deprecated = deprecated; } - @Override - public Header deprecated(Boolean deprecated) { - setDeprecated(deprecated); - return this; - } - @Override public Boolean getAllowEmptyValue() { return allowEmptyValue; @@ -146,12 +122,6 @@ public void setAllowEmptyValue(Boolean allowEmptyValue) { this.allowEmptyValue = allowEmptyValue; } - @Override - public Header allowEmptyValue(Boolean allowEmptyValue) { - setAllowEmptyValue(allowEmptyValue); - return this; - } - @Override public Style getStyle() { return style; @@ -162,12 +132,6 @@ public void setStyle(Style style) { this.style = style; } - @Override - public Header style(Style style) { - setStyle(style); - return this; - } - @Override public Boolean getExplode() { return explode; @@ -178,12 +142,6 @@ public void setExplode(Boolean explode) { this.explode = explode; } - @Override - public Header explode(Boolean explode) { - setExplode(explode); - return this; - } - @Override public Schema getSchema() { return schema; @@ -194,12 +152,6 @@ public void setSchema(Schema schema) { this.schema = schema; } - @Override - public Header schema(Schema schema) { - setSchema(schema); - return this; - } - @Override public Map getExamples() { return examples; @@ -211,15 +163,14 @@ public void setExamples(Map examples) { } @Override - public Header examples(Map examples) { - setExamples(examples); + public Header addExample(String key, Example examplesItem) { + this.examples.put(key, examplesItem); return this; } @Override - public Header addExample(String key, Example examplesItem) { - this.examples.put(key, examplesItem); - return this; + public void removeExample(String key) { + this.examples.remove(key); } @Override @@ -232,12 +183,6 @@ public void setExample(Object example) { this.example = example; } - @Override - public Header example(Object example) { - setExample(example); - return this; - } - @Override public Content getContent() { return content; @@ -248,12 +193,6 @@ public void setContent(Content content) { this.content = content; } - @Override - public Header content(Content content) { - setContent(content); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.headers.Header from, Header to, boolean override, Map currentSchemas) { if (isAnnotationNull(from)) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/ContactImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/ContactImpl.java index 169d07090c6..34e004474b3 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/ContactImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/ContactImpl.java @@ -46,7 +46,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class ContactImpl extends ExtensibleImpl implements Contact { +public class ContactImpl extends ExtensibleImpl implements Contact { protected String name; protected String url; @@ -62,12 +62,6 @@ public void setName(String name) { this.name = name; } - @Override - public Contact name(String name) { - setName(name); - return this; - } - @Override public String getUrl() { return url; @@ -78,12 +72,6 @@ public void setUrl(String url) { this.url = url; } - @Override - public Contact url(String url) { - setUrl(url); - return this; - } - @Override public String getEmail() { return email; @@ -94,12 +82,6 @@ public void setEmail(String email) { this.email = email; } - @Override - public Contact email(String email) { - setEmail(email); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.info.Contact from, Contact to, boolean override) { if (isAnnotationNull(from)) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/InfoImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/InfoImpl.java index 5405b4c12b5..fbc518115d5 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/InfoImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/InfoImpl.java @@ -48,7 +48,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class InfoImpl extends ExtensibleImpl implements Info { +public class InfoImpl extends ExtensibleImpl implements Info { protected String title; protected String description; @@ -67,12 +67,6 @@ public void setTitle(String title) { this.title = title; } - @Override - public Info title(String title) { - setTitle(title); - return this; - } - @Override public String getDescription() { return description; @@ -83,12 +77,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public Info description(String description) { - setDescription(description); - return this; - } - @Override public String getTermsOfService() { return termsOfService; @@ -99,12 +87,6 @@ public void setTermsOfService(String termsOfService) { this.termsOfService = termsOfService; } - @Override - public Info termsOfService(String termsOfService) { - setTermsOfService(termsOfService); - return this; - } - @Override public Contact getContact() { return contact; @@ -115,12 +97,6 @@ public void setContact(Contact contact) { this.contact = contact; } - @Override - public Info contact(Contact contact) { - setContact(contact); - return this; - } - @Override public License getLicense() { return license; @@ -131,12 +107,6 @@ public void setLicense(License license) { this.license = license; } - @Override - public Info license(License license) { - setLicense(license); - return this; - } - @Override public String getVersion() { return version; @@ -147,12 +117,6 @@ public void setVersion(String version) { this.version = version; } - @Override - public Info version(String version) { - setVersion(version); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.info.Info from, Info to, boolean override) { if (isAnnotationNull(from)) { return; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/LicenseImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/LicenseImpl.java index 773cf073d9c..f0e12dea008 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/LicenseImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/LicenseImpl.java @@ -46,7 +46,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class LicenseImpl extends ExtensibleImpl implements License { +public class LicenseImpl extends ExtensibleImpl implements License { protected String name; protected String url; @@ -61,12 +61,6 @@ public void setName(String name) { this.name = name; } - @Override - public License name(String name) { - setName(name); - return this; - } - @Override public String getUrl() { return url; @@ -77,12 +71,6 @@ public void setUrl(String url) { this.url = url; } - @Override - public License url(String url) { - setUrl(url); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.info.License from, License to, boolean override) { if (isAnnotationNull(from)) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java index d4929ab43b0..027d385304d 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java @@ -53,7 +53,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class LinkImpl extends ExtensibleImpl implements Link { +public class LinkImpl extends ExtensibleImpl implements Link { protected String operationRef; protected String operationId; @@ -73,12 +73,6 @@ public void setServer(Server server) { this.server = server; } - @Override - public Link server(Server server) { - setServer(server); - return this; - } - @Override public String getOperationRef() { return operationRef; @@ -89,12 +83,6 @@ public void setOperationRef(String operationRef) { this.operationRef = operationRef; } - @Override - public Link operationRef(String operationRef) { - setOperationRef(operationRef); - return this; - } - @Override public Object getRequestBody() { return requestBody; @@ -105,12 +93,6 @@ public void setRequestBody(Object requestBody) { this.requestBody = requestBody; } - @Override - public Link requestBody(Object requestBody) { - setRequestBody(requestBody); - return this; - } - @Override public String getOperationId() { return operationId; @@ -121,12 +103,6 @@ public void setOperationId(String operationId) { this.operationId = operationId; } - @Override - public Link operationId(String operationId) { - setOperationId(operationId); - return this; - } - @Override public Map getParameters() { return parameters; @@ -138,15 +114,14 @@ public void setParameters(Map parameters) { } @Override - public Link parameters(Map parameters) { - setParameters(parameters); + public Link addParameter(String name, Object parameter) { + this.parameters.put(name, parameter); return this; } @Override - public Link addParameter(String name, Object parameter) { - this.parameters.put(name, parameter); - return this; + public void removeParameter(String name) { + this.parameters.remove(name); } @Override @@ -159,12 +134,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public Link description(String description) { - setDescription(description); - return this; - } - @Override public String getRef() { return ref; @@ -178,12 +147,6 @@ public void setRef(String ref) { this.ref = ref; } - @Override - public Link ref(String ref) { - setRef(ref); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.links.Link from, Link to, boolean override) { if (isAnnotationNull(from)) { return; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java index cbe163eb295..0ee319ee614 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java @@ -56,12 +56,36 @@ public class ContentImpl extends LinkedHashMap implements Con private static final long serialVersionUID = 1575356277308242221L; + public ContentImpl() { + super(); + } + + public ContentImpl(Map items) { + super(items); + } + @Override public Content addMediaType(String name, MediaType item) { this.put(name, item); return this; } + @Override + public void removeMediaType(String name) { + remove(name); + } + + @Override + public Map getMediaTypes() { + return new ContentImpl(this); + } + + @Override + public void setMediaTypes(Map mediaTypes) { + clear(); + putAll(mediaTypes); + } + public static void merge(org.eclipse.microprofile.openapi.annotations.media.Content from, Content to, boolean override, Map currentSchemas) { if (from == null) { @@ -76,16 +100,16 @@ public static void merge(org.eclipse.microprofile.openapi.annotations.media.Cont // Get or create the corresponding media type MediaType mediaType = to.getOrDefault(typeName, new MediaTypeImpl()); - to.put(typeName, mediaType); + to.addMediaType(typeName, mediaType); // Merge encoding for (Encoding encoding : from.encoding()) { - EncodingImpl.merge(encoding, to.get(typeName).getEncoding(), override, currentSchemas); + EncodingImpl.merge(encoding, to.getMediaType(typeName).getEncoding(), override, currentSchemas); } // Merge examples for (ExampleObject example : from.examples()) { - ExampleImpl.merge(example, to.get(typeName).getExamples(), override); + ExampleImpl.merge(example, to.getMediaType(typeName).getExamples(), override); } // Merge schema diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java index c71cba9bf15..7d7754bf973 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java @@ -59,12 +59,6 @@ public void setPropertyName(String propertyName) { this.propertyName = propertyName; } - @Override - public Discriminator propertyName(String propertyName) { - setPropertyName(propertyName); - return this; - } - @Override public Map getMapping() { return mapping; @@ -75,16 +69,14 @@ public void setMapping(Map mapping) { this.mapping = mapping; } - @Override - public Discriminator mapping(Map mapping) { - setMapping(mapping); - return this; - } - @Override public Discriminator addMapping(String name, String value) { mapping.put(name, value); return this; } + @Override + public void removeMapping(String name) { + mapping.remove(name); + } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java index 4436050fdaa..94d1b82abf6 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java @@ -52,7 +52,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; import fish.payara.microprofile.openapi.impl.model.headers.HeaderImpl; -public class EncodingImpl extends ExtensibleImpl implements Encoding { +public class EncodingImpl extends ExtensibleImpl implements Encoding { protected String contentType; protected Map headers = new HashMap<>(); @@ -70,12 +70,6 @@ public void setContentType(String contentType) { this.contentType = contentType; } - @Override - public Encoding contentType(String contentType) { - setContentType(contentType); - return this; - } - @Override public Map getHeaders() { return headers; @@ -87,11 +81,16 @@ public void setHeaders(Map headers) { } @Override - public Encoding headers(Map headers) { - setHeaders(headers); + public Encoding addHeader(String key, Header header) { + headers.put(key, header); return this; } + @Override + public void removeHeader(String key) { + headers.remove(key); + } + @Override public Style getStyle() { return style; @@ -102,12 +101,6 @@ public void setStyle(Style style) { this.style = style; } - @Override - public Encoding style(Style style) { - setStyle(style); - return this; - } - @Override public Boolean getExplode() { return explode; @@ -118,12 +111,6 @@ public void setExplode(Boolean explode) { this.explode = explode; } - @Override - public Encoding explode(Boolean explode) { - setExplode(explode); - return this; - } - @Override public Boolean getAllowReserved() { return allowReserved; @@ -134,12 +121,6 @@ public void setAllowReserved(Boolean allowReserved) { this.allowReserved = allowReserved; } - @Override - public Encoding allowReserved(Boolean allowReserved) { - setAllowReserved(allowReserved); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.media.Encoding from, Encoding to, boolean override, Map currentSchemas) { if (isAnnotationNull(from)) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java index f24e84c62d9..febfa6ed3d5 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java @@ -49,7 +49,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class MediaTypeImpl extends ExtensibleImpl implements MediaType { +public class MediaTypeImpl extends ExtensibleImpl implements MediaType { protected Schema schema; protected Map examples = new HashMap<>(); @@ -66,12 +66,6 @@ public void setSchema(Schema schema) { this.schema = schema; } - @Override - public MediaType schema(Schema schema) { - setSchema(schema); - return this; - } - @Override public Map getExamples() { return examples; @@ -83,15 +77,14 @@ public void setExamples(Map examples) { } @Override - public MediaType examples(Map examples) { - setExamples(examples); + public MediaType addExample(String key, Example example) { + this.examples.put(key, example); return this; } @Override - public MediaType addExample(String key, Example example) { - this.examples.put(key, example); - return this; + public void removeExample(String key) { + this.examples.remove(key); } @Override @@ -104,12 +97,6 @@ public void setExample(Object example) { this.example = example; } - @Override - public MediaType example(Object example) { - setExample(example); - return this; - } - @Override public Map getEncoding() { return encoding; @@ -121,15 +108,14 @@ public void setEncoding(Map encoding) { } @Override - public MediaType encoding(Map encoding) { - setEncoding(encoding); + public MediaType addEncoding(String key, Encoding encodingItem) { + this.encoding.put(key, encodingItem); return this; } @Override - public MediaType addEncoding(String key, Encoding encodingItem) { - this.encoding.put(key, encodingItem); - return this; + public void removeEncoding(String key) { + this.encoding.remove(key); } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java index 3fd065d0480..c13a71a8267 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java @@ -62,7 +62,7 @@ import fish.payara.microprofile.openapi.impl.model.ExternalDocumentationImpl; import fish.payara.microprofile.openapi.impl.model.util.ModelUtils; -public class SchemaImpl extends ExtensibleImpl implements Schema { +public class SchemaImpl extends ExtensibleImpl implements Schema { private static final Logger LOGGER = Logger.getLogger(SchemaImpl.class.getName()); @@ -116,12 +116,6 @@ public void setDiscriminator(Discriminator discriminator) { this.discriminator = discriminator; } - @Override - public Schema discriminator(Discriminator discriminator) { - setDiscriminator(discriminator); - return this; - } - @Override public String getTitle() { return title; @@ -132,12 +126,6 @@ public void setTitle(String title) { this.title = title; } - @Override - public Schema title(String title) { - setTitle(title); - return this; - } - @Override public Object getDefaultValue() { return defaultValue; @@ -148,12 +136,6 @@ public void setDefaultValue(Object defaultValue) { this.defaultValue = defaultValue; } - @Override - public Schema defaultValue(Object defaultValue) { - setDefaultValue(defaultValue); - return this; - } - @Override public List getEnumeration() { return enumeration; @@ -170,6 +152,11 @@ public Schema addEnumeration(Object enumerationItem) { return this; } + @Override + public void removeEnumeration(Object enumeration) { + this.enumeration.remove(enumeration); + } + @Override public BigDecimal getMultipleOf() { return multipleOf; @@ -180,12 +167,6 @@ public void setMultipleOf(BigDecimal multipleOf) { this.multipleOf = multipleOf; } - @Override - public Schema multipleOf(BigDecimal multipleOf) { - setMultipleOf(multipleOf); - return this; - } - @Override public BigDecimal getMaximum() { return maximum; @@ -196,12 +177,6 @@ public void setMaximum(BigDecimal maximum) { this.maximum = maximum; } - @Override - public Schema maximum(BigDecimal maximum) { - setMaximum(maximum); - return this; - } - @Override public Boolean getExclusiveMaximum() { return exclusiveMaximum; @@ -212,12 +187,6 @@ public void setExclusiveMaximum(Boolean exclusiveMaximum) { this.exclusiveMaximum = exclusiveMaximum; } - @Override - public Schema exclusiveMaximum(Boolean exclusiveMaximum) { - setExclusiveMaximum(exclusiveMaximum); - return this; - } - @Override public BigDecimal getMinimum() { return minimum; @@ -228,12 +197,6 @@ public void setMinimum(BigDecimal minimum) { this.minimum = minimum; } - @Override - public Schema minimum(BigDecimal minimum) { - setMinimum(minimum); - return this; - } - @Override public Boolean getExclusiveMinimum() { return exclusiveMinimum; @@ -244,12 +207,6 @@ public void setExclusiveMinimum(Boolean exclusiveMinimum) { this.exclusiveMinimum = exclusiveMinimum; } - @Override - public Schema exclusiveMinimum(Boolean exclusiveMinimum) { - setExclusiveMinimum(exclusiveMinimum); - return this; - } - @Override public Integer getMaxLength() { return maxLength; @@ -260,12 +217,6 @@ public void setMaxLength(Integer maxLength) { this.maxLength = maxLength; } - @Override - public Schema maxLength(Integer maxLength) { - setMaxLength(maxLength); - return this; - } - @Override public Integer getMinLength() { return minLength; @@ -276,12 +227,6 @@ public void setMinLength(Integer minLength) { this.minLength = minLength; } - @Override - public Schema minLength(Integer minLength) { - setMinLength(minLength); - return this; - } - @Override public String getPattern() { return pattern; @@ -292,12 +237,6 @@ public void setPattern(String pattern) { this.pattern = pattern; } - @Override - public Schema pattern(String pattern) { - setPattern(pattern); - return this; - } - @Override public Integer getMaxItems() { return maxItems; @@ -308,12 +247,6 @@ public void setMaxItems(Integer maxItems) { this.maxItems = maxItems; } - @Override - public Schema maxItems(Integer maxItems) { - setMaxItems(maxItems); - return this; - } - @Override public Integer getMinItems() { return minItems; @@ -324,12 +257,6 @@ public void setMinItems(Integer minItems) { this.minItems = minItems; } - @Override - public Schema minItems(Integer minItems) { - setMinItems(minItems); - return this; - } - @Override public Boolean getUniqueItems() { return uniqueItems; @@ -340,12 +267,6 @@ public void setUniqueItems(Boolean uniqueItems) { this.uniqueItems = uniqueItems; } - @Override - public Schema uniqueItems(Boolean uniqueItems) { - setUniqueItems(uniqueItems); - return this; - } - @Override public Integer getMaxProperties() { return maxProperties; @@ -356,12 +277,6 @@ public void setMaxProperties(Integer maxProperties) { this.maxProperties = maxProperties; } - @Override - public Schema maxProperties(Integer maxProperties) { - setMaxProperties(maxProperties); - return this; - } - @Override public Integer getMinProperties() { return minProperties; @@ -372,12 +287,6 @@ public void setMinProperties(Integer minProperties) { this.minProperties = minProperties; } - @Override - public Schema minProperties(Integer minProperties) { - setMinProperties(minProperties); - return this; - } - @Override public List getRequired() { return required; @@ -388,12 +297,6 @@ public void setRequired(List required) { this.required = required; } - @Override - public Schema required(List required) { - setRequired(required); - return this; - } - @Override public Schema addRequired(String requiredItem) { this.required.add(requiredItem); @@ -401,6 +304,11 @@ public Schema addRequired(String requiredItem) { return this; } + @Override + public void removeRequired(String required) { + this.required.remove(required); + } + @Override public SchemaType getType() { return type; @@ -411,12 +319,6 @@ public void setType(SchemaType type) { this.type = type; } - @Override - public Schema type(SchemaType type) { - setType(type); - return this; - } - @Override public Schema getNot() { return not; @@ -427,12 +329,6 @@ public void setNot(Schema not) { this.not = not; } - @Override - public Schema not(Schema not) { - setNot(not); - return this; - } - @Override public Map getProperties() { return properties; @@ -444,15 +340,14 @@ public void setProperties(Map properties) { } @Override - public Schema properties(Map properties) { - setProperties(properties); + public Schema addProperty(String key, Schema propertiesItem) { + this.properties.put(key, propertiesItem); return this; } @Override - public Schema addProperty(String key, Schema propertiesItem) { - this.properties.put(key, propertiesItem); - return this; + public void removeProperty(String key) { + this.properties.remove(key); } @Override @@ -466,9 +361,23 @@ public void setAdditionalProperties(Schema additionalProperties) { } @Override - public Schema additionalProperties(Schema additionalProperties) { - setAdditionalProperties(additionalProperties); - return this; + public Schema getAdditionalPropertiesSchema() { + return (Schema) additionalProperties; + } + + @Override + public Boolean getAdditionalPropertiesBoolean() { + return (Boolean) additionalProperties; + } + + @Override + public void setAdditionalPropertiesSchema(Schema additionalProperties) { + this.additionalProperties = additionalProperties; + } + + @Override + public void setAdditionalPropertiesBoolean(Boolean additionalProperties) { + this.additionalProperties = additionalProperties; } @Override @@ -481,12 +390,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public Schema description(String description) { - setDescription(description); - return this; - } - @Override public String getFormat() { return format; @@ -497,12 +400,6 @@ public void setFormat(String format) { this.format = format; } - @Override - public Schema format(String format) { - setFormat(format); - return this; - } - @Override public String getRef() { return ref; @@ -516,12 +413,6 @@ public void setRef(String ref) { this.ref = ref; } - @Override - public Schema ref(String ref) { - setRef(ref); - return this; - } - @Override public Boolean getNullable() { return nullable; @@ -532,12 +423,6 @@ public void setNullable(Boolean nullable) { this.nullable = nullable; } - @Override - public Schema nullable(Boolean nullable) { - setNullable(nullable); - return this; - } - @Override public Boolean getReadOnly() { return readOnly; @@ -548,12 +433,6 @@ public void setReadOnly(Boolean readOnly) { this.readOnly = readOnly; } - @Override - public Schema readOnly(Boolean readOnly) { - setReadOnly(readOnly); - return this; - } - @Override public Boolean getWriteOnly() { return writeOnly; @@ -564,12 +443,6 @@ public void setWriteOnly(Boolean writeOnly) { this.writeOnly = writeOnly; } - @Override - public Schema writeOnly(Boolean writeOnly) { - setWriteOnly(writeOnly); - return this; - } - @Override public Object getExample() { return example; @@ -580,12 +453,6 @@ public void setExample(Object example) { this.example = example; } - @Override - public Schema example(Object example) { - setExample(example); - return this; - } - @Override public ExternalDocumentation getExternalDocs() { return externalDocs; @@ -596,12 +463,6 @@ public void setExternalDocs(ExternalDocumentation externalDocs) { this.externalDocs = externalDocs; } - @Override - public Schema externalDocs(ExternalDocumentation externalDocs) { - setExternalDocs(externalDocs); - return this; - } - @Override public Boolean getDeprecated() { return deprecated; @@ -612,12 +473,6 @@ public void setDeprecated(Boolean deprecated) { this.deprecated = deprecated; } - @Override - public Schema deprecated(Boolean deprecated) { - setDeprecated(deprecated); - return this; - } - @Override public XML getXml() { return xml; @@ -628,12 +483,6 @@ public void setXml(XML xml) { this.xml = xml; } - @Override - public Schema xml(XML xml) { - setXml(xml); - return this; - } - @Override public Schema enumeration(List enumeration) { setEnumeration(enumeration); @@ -650,12 +499,6 @@ public void setItems(Schema items) { this.items = items; } - @Override - public Schema items(Schema items) { - setItems(items); - return this; - } - @Override public List getAllOf() { return allOf; @@ -667,15 +510,14 @@ public void setAllOf(List allOf) { } @Override - public Schema allOf(List allOf) { - setAllOf(allOf); + public Schema addAllOf(Schema allOf) { + this.allOf.add(allOf); return this; } @Override - public Schema addAllOf(Schema allOf) { - this.allOf.add(allOf); - return this; + public void removeAllOf(Schema allOf) { + this.allOf.remove(allOf); } @Override @@ -689,15 +531,14 @@ public void setAnyOf(List anyOf) { } @Override - public Schema anyOf(List anyOf) { - setAnyOf(anyOf); + public Schema addAnyOf(Schema anyOf) { + this.anyOf.add(anyOf); return this; } @Override - public Schema addAnyOf(Schema anyOf) { - this.anyOf.add(anyOf); - return this; + public void removeAnyOf(Schema anyOf) { + this.anyOf.remove(anyOf); } @Override @@ -710,12 +551,6 @@ public void setOneOf(List oneOf) { this.oneOf = oneOf; } - @Override - public Schema oneOf(List oneOf) { - setOneOf(oneOf); - return this; - } - @Override public Schema addOneOf(Schema oneOf) { this.oneOf.add(oneOf); @@ -723,14 +558,13 @@ public Schema addOneOf(Schema oneOf) { } @Override - public void setAdditionalProperties(Boolean additionalProperties) { - this.additionalProperties = additionalProperties; + public void removeOneOf(Schema oneOf) { + this.oneOf.remove(oneOf); } @Override - public Schema additionalProperties(Boolean additionalProperties) { - setAdditionalProperties(additionalProperties); - return this; + public void setAdditionalProperties(Boolean additionalProperties) { + this.additionalProperties = additionalProperties; } public static void merge(org.eclipse.microprofile.openapi.annotations.media.Schema from, Schema to, diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/XMLImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/XMLImpl.java index 479d480bd26..f27a34ffbe3 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/XMLImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/XMLImpl.java @@ -43,7 +43,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class XMLImpl extends ExtensibleImpl implements XML { +public class XMLImpl extends ExtensibleImpl implements XML { protected String name; protected String namespace; @@ -61,12 +61,6 @@ public void setName(String name) { this.name = name; } - @Override - public XML name(String name) { - setName(name); - return this; - } - @Override public String getNamespace() { return namespace; @@ -77,12 +71,6 @@ public void setNamespace(String namespace) { this.namespace = namespace; } - @Override - public XML namespace(String namespace) { - setNamespace(namespace); - return this; - } - @Override public String getPrefix() { return prefix; @@ -93,12 +81,6 @@ public void setPrefix(String prefix) { this.prefix = prefix; } - @Override - public XML prefix(String prefix) { - setPrefix(prefix); - return this; - } - @Override public Boolean getAttribute() { return attribute; @@ -109,12 +91,6 @@ public void setAttribute(Boolean attribute) { this.attribute = attribute; } - @Override - public XML attribute(Boolean attribute) { - setAttribute(attribute); - return this; - } - @Override public Boolean getWrapped() { return wrapped; @@ -125,10 +101,4 @@ public void setWrapped(Boolean wrapped) { this.wrapped = wrapped; } - @Override - public XML wrapped(Boolean wrapped) { - setWrapped(wrapped); - return this; - } - } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java index 786381a65bd..070d44b218a 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java @@ -60,7 +60,7 @@ import fish.payara.microprofile.openapi.impl.model.media.ContentImpl; import fish.payara.microprofile.openapi.impl.model.media.SchemaImpl; -public class ParameterImpl extends ExtensibleImpl implements Parameter { +public class ParameterImpl extends ExtensibleImpl implements Parameter { protected String name; protected In in; @@ -88,12 +88,6 @@ public void setName(String name) { this.name = name; } - @Override - public Parameter name(String name) { - setName(name); - return this; - } - @Override public In getIn() { return in; @@ -104,12 +98,6 @@ public void setIn(In in) { this.in = in; } - @Override - public Parameter in(In in) { - setIn(in); - return this; - } - @Override public String getDescription() { return description; @@ -120,12 +108,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public Parameter description(String description) { - setDescription(description); - return this; - } - @Override public Boolean getRequired() { return required; @@ -136,12 +118,6 @@ public void setRequired(Boolean required) { this.required = required; } - @Override - public Parameter required(Boolean required) { - setRequired(required); - return this; - } - @Override public Boolean getDeprecated() { return deprecated; @@ -152,12 +128,6 @@ public void setDeprecated(Boolean deprecated) { this.deprecated = deprecated; } - @Override - public Parameter deprecated(Boolean deprecated) { - setDeprecated(deprecated); - return this; - } - @Override public Boolean getAllowEmptyValue() { return allowEmptyValue; @@ -168,12 +138,6 @@ public void setAllowEmptyValue(Boolean allowEmptyValue) { this.allowEmptyValue = allowEmptyValue; } - @Override - public Parameter allowEmptyValue(Boolean allowEmptyValue) { - setAllowEmptyValue(allowEmptyValue); - return this; - } - @Override public Style getStyle() { return style; @@ -184,12 +148,6 @@ public void setStyle(Style style) { this.style = style; } - @Override - public Parameter style(Style style) { - setStyle(style); - return this; - } - @Override public Boolean getExplode() { return explode; @@ -200,12 +158,6 @@ public void setExplode(Boolean explode) { this.explode = explode; } - @Override - public Parameter explode(Boolean explode) { - setExplode(explode); - return this; - } - @Override public Boolean getAllowReserved() { return allowReserved; @@ -216,12 +168,6 @@ public void setAllowReserved(Boolean allowReserved) { this.allowReserved = allowReserved; } - @Override - public Parameter allowReserved(Boolean allowReserved) { - setAllowReserved(allowReserved); - return this; - } - @Override public Schema getSchema() { return schema; @@ -232,12 +178,6 @@ public void setSchema(Schema schema) { this.schema = schema; } - @Override - public Parameter schema(Schema schema) { - setSchema(schema); - return this; - } - @Override public Map getExamples() { return examples; @@ -249,15 +189,14 @@ public void setExamples(Map examples) { } @Override - public Parameter examples(Map examples) { - setExamples(examples); + public Parameter addExample(String key, Example example) { + this.examples.put(key, example); return this; } @Override - public Parameter addExample(String key, Example example) { - this.examples.put(key, example); - return this; + public void removeExample(String key) { + this.examples.remove(key); } @Override @@ -270,12 +209,6 @@ public void setExample(Object example) { this.example = example; } - @Override - public Parameter example(Object example) { - setExample(example); - return this; - } - @Override public Content getContent() { return content; @@ -286,12 +219,6 @@ public void setContent(Content content) { this.content = content; } - @Override - public Parameter content(Content content) { - setContent(content); - return this; - } - @Override public String getRef() { return ref; @@ -305,12 +232,6 @@ public void setRef(String ref) { this.ref = ref; } - @Override - public Parameter ref(String ref) { - setRef(ref); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.parameters.Parameter from, Parameter to, boolean override, Map currentSchemas) { if (isAnnotationNull(from)) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/RequestBodyImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/RequestBodyImpl.java index 6843fea8aaa..73f0d7329a3 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/RequestBodyImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/RequestBodyImpl.java @@ -52,7 +52,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; import fish.payara.microprofile.openapi.impl.model.media.ContentImpl; -public class RequestBodyImpl extends ExtensibleImpl implements RequestBody { +public class RequestBodyImpl extends ExtensibleImpl implements RequestBody { protected String description; protected Content content = new ContentImpl(); @@ -69,12 +69,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public RequestBody description(String description) { - setDescription(description); - return this; - } - @Override public Content getContent() { return content; @@ -85,12 +79,6 @@ public void setContent(Content content) { this.content = content; } - @Override - public RequestBody content(Content content) { - setContent(content); - return this; - } - @Override public Boolean getRequired() { return required; @@ -101,12 +89,6 @@ public void setRequired(Boolean required) { this.required = required; } - @Override - public RequestBody required(Boolean required) { - setRequired(required); - return this; - } - @Override public String getRef() { return ref; @@ -120,12 +102,6 @@ public void setRef(String ref) { this.ref = ref; } - @Override - public RequestBody ref(String ref) { - setRef(ref); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.parameters.RequestBody from, RequestBody to, boolean override, Map currentSchemas) { if (isAnnotationNull(from)) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java index feb2f7ea4e2..498247f378e 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java @@ -57,7 +57,7 @@ import fish.payara.microprofile.openapi.impl.model.links.LinkImpl; import fish.payara.microprofile.openapi.impl.model.media.ContentImpl; -public class APIResponseImpl extends ExtensibleImpl implements APIResponse { +public class APIResponseImpl extends ExtensibleImpl implements APIResponse { protected String description; protected Map headers = new HashMap<>(); @@ -75,12 +75,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public APIResponse description(String description) { - setDescription(description); - return this; - } - @Override public Map getHeaders() { return headers; @@ -92,15 +86,14 @@ public void setHeaders(Map headers) { } @Override - public APIResponse headers(Map headers) { - setHeaders(headers); + public APIResponse addHeader(String name, Header header) { + headers.put(name, header); return this; } @Override - public APIResponse addHeader(String name, Header header) { - headers.put(name, header); - return this; + public void removeHeader(String name) { + headers.remove(name); } @Override @@ -113,12 +106,6 @@ public void setContent(Content content) { this.content = content; } - @Override - public APIResponse content(Content content) { - setContent(content); - return this; - } - @Override public Map getLinks() { return links; @@ -130,15 +117,14 @@ public void setLinks(Map links) { } @Override - public APIResponse links(Map links) { - setLinks(links); + public APIResponse addLink(String name, Link link) { + links.put(name, link); return this; } @Override - public APIResponse addLink(String name, Link link) { - links.put(name, link); - return this; + public void removeLink(String name) { + links.remove(name); } @Override @@ -154,12 +140,6 @@ public void setRef(String ref) { this.ref = ref; } - @Override - public APIResponse ref(String ref) { - setRef(ref); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.responses.APIResponse from, APIResponse to, boolean override, Map currentSchemas) { if (isAnnotationNull(from)) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java index 19ae86f59a4..b2f800b3878 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java @@ -41,37 +41,60 @@ import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.isAnnotationNull; -import java.util.LinkedHashMap; +import java.util.HashMap; import java.util.Map; import org.eclipse.microprofile.openapi.models.media.Schema; import org.eclipse.microprofile.openapi.models.responses.APIResponse; import org.eclipse.microprofile.openapi.models.responses.APIResponses; -public class APIResponsesImpl extends LinkedHashMap implements APIResponses { +import fish.payara.microprofile.openapi.impl.model.ExtensibleLinkedHashMap; + +public class APIResponsesImpl extends ExtensibleLinkedHashMap + implements APIResponses { private static final long serialVersionUID = 2811935761440110541L; - @Override - public APIResponses addApiResponse(String name, APIResponse item) { - put(name, item); + protected Map extensions = new HashMap<>(); + + public APIResponsesImpl() { + super(); + } + + public APIResponsesImpl(Map responses) { + super(responses); + } + + @Override + public APIResponses addAPIResponse(String name, APIResponse apiResponse) { + put(name, apiResponse); return this; } @Override - public APIResponse getDefault() { - return this.get(DEFAULT); + public void removeAPIResponse(String name) { + remove(name); } @Override - public void setDefaultValue(APIResponse defaultValue) { - addApiResponse(DEFAULT, defaultValue); + public Map getAPIResponses() { + return new APIResponsesImpl(this); } @Override - public APIResponses defaultValue(APIResponse defaultValue) { - setDefaultValue(defaultValue); - return this; + public void setAPIResponses(Map items) { + clear(); + putAll(items); + } + + @Override + public APIResponse getDefaultValue() { + return this.get(DEFAULT); + } + + @Override + public void setDefaultValue(APIResponse defaultValue) { + addAPIResponse(DEFAULT, defaultValue); } public static void merge(org.eclipse.microprofile.openapi.annotations.responses.APIResponse from, APIResponses to, @@ -87,7 +110,7 @@ public static void merge(org.eclipse.microprofile.openapi.annotations.responses. org.eclipse.microprofile.openapi.models.responses.APIResponse response = to .getOrDefault(responseName, new APIResponseImpl()); - to.addApiResponse(responseName, response); + to.addAPIResponse(responseName, response); APIResponseImpl.merge(from, response, override, currentSchemas); } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowImpl.java index 74f3d2ebaf9..e6ad4daa23c 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowImpl.java @@ -48,7 +48,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class OAuthFlowImpl extends ExtensibleImpl implements OAuthFlow { +public class OAuthFlowImpl extends ExtensibleImpl implements OAuthFlow { protected String authorizationUrl; protected String tokenUrl; @@ -65,12 +65,6 @@ public void setAuthorizationUrl(String authorizationUrl) { this.authorizationUrl = authorizationUrl; } - @Override - public OAuthFlow authorizationUrl(String authorizationUrl) { - setAuthorizationUrl(authorizationUrl); - return this; - } - @Override public String getTokenUrl() { return tokenUrl; @@ -81,12 +75,6 @@ public void setTokenUrl(String tokenUrl) { this.tokenUrl = tokenUrl; } - @Override - public OAuthFlow tokenUrl(String tokenUrl) { - setTokenUrl(tokenUrl); - return this; - } - @Override public String getRefreshUrl() { return refreshUrl; @@ -97,12 +85,6 @@ public void setRefreshUrl(String refreshUrl) { this.refreshUrl = refreshUrl; } - @Override - public OAuthFlow refreshUrl(String refreshUrl) { - setRefreshUrl(refreshUrl); - return this; - } - @Override public Scopes getScopes() { return scopes; @@ -113,12 +95,6 @@ public void setScopes(Scopes scopes) { this.scopes = scopes; } - @Override - public OAuthFlow scopes(Scopes scopes) { - setScopes(scopes); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.security.OAuthFlow from, OAuthFlow to, boolean override) { if (isAnnotationNull(from)) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowsImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowsImpl.java index bd46c9afa3e..330324c787b 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowsImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowsImpl.java @@ -47,7 +47,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class OAuthFlowsImpl extends ExtensibleImpl implements OAuthFlows { +public class OAuthFlowsImpl extends ExtensibleImpl implements OAuthFlows { protected OAuthFlow implicit; protected OAuthFlow password; @@ -64,12 +64,6 @@ public void setImplicit(OAuthFlow implicit) { this.implicit = implicit; } - @Override - public OAuthFlows implicit(OAuthFlow implicit) { - setImplicit(implicit); - return this; - } - @Override public OAuthFlow getPassword() { return password; @@ -80,12 +74,6 @@ public void setPassword(OAuthFlow password) { this.password = password; } - @Override - public OAuthFlows password(OAuthFlow password) { - setPassword(password); - return this; - } - @Override public OAuthFlow getClientCredentials() { return clientCredentials; @@ -96,12 +84,6 @@ public void setClientCredentials(OAuthFlow clientCredentials) { this.clientCredentials = clientCredentials; } - @Override - public OAuthFlows clientCredentials(OAuthFlow clientCredentials) { - setClientCredentials(clientCredentials); - return this; - } - @Override public OAuthFlow getAuthorizationCode() { return authorizationCode; @@ -112,12 +94,6 @@ public void setAuthorizationCode(OAuthFlow authorizationCode) { this.authorizationCode = authorizationCode; } - @Override - public OAuthFlows authorizationCode(OAuthFlow authorizationCode) { - setAuthorizationCode(authorizationCode); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.security.OAuthFlows from, OAuthFlows to, boolean override) { if (from == null) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java index 20f58d4b0bb..1ed1852075f 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java @@ -39,17 +39,23 @@ */ package fish.payara.microprofile.openapi.impl.model.security; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.microprofile.openapi.models.security.Scopes; -public class ScopesImpl extends LinkedHashMap implements Scopes { +import fish.payara.microprofile.openapi.impl.model.ExtensibleLinkedHashMap; + +public class ScopesImpl extends ExtensibleLinkedHashMap implements Scopes { private static final long serialVersionUID = -615440059031779085L; - protected Map extensions = new HashMap<>(); + public ScopesImpl() { + super(); + } + + public ScopesImpl(Map scopes) { + super(scopes); + } @Override public Scopes addScope(String name, String item) { @@ -58,18 +64,19 @@ public Scopes addScope(String name, String item) { } @Override - public Map getExtensions() { - return extensions; + public void removeScope(String scope) { + this.remove(scope); } @Override - public void setExtensions(Map extensions) { - this.extensions = extensions; + public Map getScopes() { + return new ScopesImpl(this); } @Override - public void addExtension(String name, Object value) { - this.extensions.put(name, value); + public void setScopes(Map items) { + clear(); + putAll(items); } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecurityRequirementImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecurityRequirementImpl.java index 0706cb66f5b..381e2b1789a 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecurityRequirementImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecurityRequirementImpl.java @@ -45,6 +45,7 @@ import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import org.eclipse.microprofile.openapi.models.security.SecurityRequirement; @@ -52,6 +53,14 @@ public class SecurityRequirementImpl extends LinkedHashMap> private static final long serialVersionUID = -677783376083861245L; + public SecurityRequirementImpl() { + super(); + } + + public SecurityRequirementImpl(Map> items) { + super(items); + } + @Override public SecurityRequirement addScheme(String name, String item) { this.put(name, Arrays.asList(item)); @@ -70,6 +79,22 @@ public SecurityRequirement addScheme(String name) { return this; } + @Override + public void removeScheme(String securitySchemeName) { + this.remove(securitySchemeName); + } + + @Override + public Map> getSchemes() { + return new SecurityRequirementImpl(this); + } + + @Override + public void setSchemes(Map> items) { + clear(); + putAll(items); + } + public static void merge(org.eclipse.microprofile.openapi.annotations.security.SecurityRequirement from, SecurityRequirement to) { if (isAnnotationNull(from)) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecuritySchemeImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecuritySchemeImpl.java index 1f710ee2dc6..c8a39503dc2 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecuritySchemeImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecuritySchemeImpl.java @@ -50,7 +50,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class SecuritySchemeImpl extends ExtensibleImpl implements SecurityScheme { +public class SecuritySchemeImpl extends ExtensibleImpl implements SecurityScheme { protected SecurityScheme.Type type; protected String description; @@ -73,12 +73,6 @@ public void setType(SecurityScheme.Type type) { this.type = type; } - @Override - public SecurityScheme type(SecurityScheme.Type type) { - setType(type); - return this; - } - @Override public String getDescription() { return description; @@ -89,12 +83,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public SecurityScheme description(String description) { - setDescription(description); - return this; - } - @Override public String getName() { return name; @@ -105,12 +93,6 @@ public void setName(String name) { this.name = name; } - @Override - public SecurityScheme name(String name) { - setName(name); - return this; - } - @Override public SecurityScheme.In getIn() { return in; @@ -121,12 +103,6 @@ public void setIn(SecurityScheme.In in) { this.in = in; } - @Override - public SecurityScheme in(SecurityScheme.In in) { - setIn(in); - return this; - } - @Override public String getScheme() { return scheme; @@ -137,12 +113,6 @@ public void setScheme(String scheme) { this.scheme = scheme; } - @Override - public SecurityScheme scheme(String scheme) { - setScheme(scheme); - return this; - } - @Override public String getBearerFormat() { return bearerFormat; @@ -153,12 +123,6 @@ public void setBearerFormat(String bearerFormat) { this.bearerFormat = bearerFormat; } - @Override - public SecurityScheme bearerFormat(String bearerFormat) { - setBearerFormat(bearerFormat); - return this; - } - @Override public OAuthFlows getFlows() { return flows; @@ -169,12 +133,6 @@ public void setFlows(OAuthFlows flows) { this.flows = flows; } - @Override - public SecurityScheme flows(OAuthFlows flows) { - setFlows(flows); - return this; - } - @Override public String getOpenIdConnectUrl() { return openIdConnectUrl; @@ -185,12 +143,6 @@ public void setOpenIdConnectUrl(String openIdConnectUrl) { this.openIdConnectUrl = openIdConnectUrl; } - @Override - public SecurityScheme openIdConnectUrl(String openIdConnectUrl) { - setOpenIdConnectUrl(openIdConnectUrl); - return this; - } - @Override public String getRef() { return ref; @@ -204,12 +156,6 @@ public void setRef(String ref) { this.ref = ref; } - @Override - public SecurityScheme ref(String ref) { - setRef(ref); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.security.SecurityScheme from, SecurityScheme to, boolean override) { if (isAnnotationNull(from)) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java index 7147050d097..c32d9d2c264 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java @@ -42,17 +42,19 @@ import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.isAnnotationNull; import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.mergeProperty; -import org.eclipse.microprofile.openapi.annotations.servers.ServerVariable; +import java.util.Map; + import org.eclipse.microprofile.openapi.models.servers.Server; +import org.eclipse.microprofile.openapi.models.servers.ServerVariable; import org.eclipse.microprofile.openapi.models.servers.ServerVariables; import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class ServerImpl extends ExtensibleImpl implements Server { +public class ServerImpl extends ExtensibleImpl implements Server { protected String url; protected String description; - protected ServerVariables variables; + protected Map variables; @Override public String getUrl() { @@ -64,12 +66,6 @@ public void setUrl(String url) { this.url = url; } - @Override - public Server url(String url) { - setUrl(url); - return this; - } - @Override public String getDescription() { return description; @@ -80,15 +76,9 @@ public void setDescription(String description) { this.description = description; } - @Override - public Server description(String description) { - setDescription(description); - return this; - } - @Override public ServerVariables getVariables() { - return variables; + return variables instanceof ServerVariables ? (ServerVariables) variables : new ServerVariablesImpl(variables); } @Override @@ -97,9 +87,8 @@ public void setVariables(ServerVariables variables) { } @Override - public Server variables(ServerVariables variables) { - setVariables(variables); - return this; + public void setVariables(Map variables) { + this.variables = variables; } public static void merge(org.eclipse.microprofile.openapi.annotations.servers.Server from, Server to, @@ -113,7 +102,7 @@ public static void merge(org.eclipse.microprofile.openapi.annotations.servers.Se if (to.getVariables() == null) { to.setVariables(new ServerVariablesImpl()); } - for (ServerVariable variable : from.variables()) { + for (org.eclipse.microprofile.openapi.annotations.servers.ServerVariable variable : from.variables()) { ServerVariablesImpl.merge(variable, to.getVariables(), override); } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java index 188a649505e..b180b25f34f 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java @@ -46,7 +46,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; -public class ServerVariableImpl extends ExtensibleImpl implements ServerVariable { +public class ServerVariableImpl extends ExtensibleImpl implements ServerVariable { protected String description; protected String defaultValue; @@ -63,12 +63,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public ServerVariable description(String description) { - setDescription(description); - return this; - } - @Override public String getDefaultValue() { return defaultValue; @@ -79,12 +73,6 @@ public void setDefaultValue(String defaultValue) { this.defaultValue = defaultValue; } - @Override - public ServerVariable defaultValue(String defaultValue) { - setDefaultValue(defaultValue); - return this; - } - @Override public List getEnumeration() { return enumeration; @@ -95,12 +83,6 @@ public void setEnumeration(List enumeration) { this.enumeration = enumeration; } - @Override - public ServerVariable enumeration(List enumeration) { - setEnumeration(enumeration); - return this; - } - @Override public ServerVariable addEnumeration(String enumeration) { if (!this.enumeration.contains(enumeration)) { @@ -109,4 +91,9 @@ public ServerVariable addEnumeration(String enumeration) { return this; } + @Override + public void removeEnumeration(String enumeration) { + this.enumeration.remove(enumeration); + } + } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java index c0fec9e06bc..ee22abd091c 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java @@ -43,18 +43,24 @@ import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.mergeProperty; import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.microprofile.openapi.models.servers.ServerVariable; import org.eclipse.microprofile.openapi.models.servers.ServerVariables; -public class ServerVariablesImpl extends LinkedHashMap implements ServerVariables { +import fish.payara.microprofile.openapi.impl.model.ExtensibleLinkedHashMap; + +public class ServerVariablesImpl extends ExtensibleLinkedHashMap implements ServerVariables { private static final long serialVersionUID = 8869393484826870024L; - protected Map extensions = new HashMap<>(); + public ServerVariablesImpl() { + super(); + } + + public ServerVariablesImpl(Map variables) { + super(variables); + } @Override public ServerVariables addServerVariable(String name, ServerVariable item) { @@ -63,18 +69,19 @@ public ServerVariables addServerVariable(String name, ServerVariable item) { } @Override - public Map getExtensions() { - return extensions; + public void removeServerVariable(String name) { + remove(name); } @Override - public void setExtensions(Map extensions) { - this.extensions = extensions; + public Map getServerVariables() { + return new ServerVariablesImpl(this); } @Override - public void addExtension(String name, Object value) { - this.extensions.put(name, value); + public void setServerVariables(Map items) { + clear(); + putAll(items); } public static void merge(org.eclipse.microprofile.openapi.annotations.servers.ServerVariable from, @@ -93,7 +100,7 @@ public static void merge(org.eclipse.microprofile.openapi.annotations.servers.Se variable.addEnumeration(value); } } - if ((to.containsKey(from.name()) && override) || !to.containsKey(from.name())) { + if ((to.hasServerVariable(from.name()) && override) || !to.hasServerVariable(from.name())) { to.addServerVariable(from.name(), variable); } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/tags/TagImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/tags/TagImpl.java index 8b9c56e7c11..8610c01f985 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/tags/TagImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/tags/TagImpl.java @@ -51,7 +51,7 @@ import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; import fish.payara.microprofile.openapi.impl.model.ExternalDocumentationImpl; -public class TagImpl extends ExtensibleImpl implements Tag { +public class TagImpl extends ExtensibleImpl implements Tag { protected String name; protected String description; @@ -67,12 +67,6 @@ public void setName(String name) { this.name = name; } - @Override - public Tag name(String name) { - setName(name); - return this; - } - @Override public String getDescription() { return description; @@ -83,12 +77,6 @@ public void setDescription(String description) { this.description = description; } - @Override - public Tag description(String description) { - setDescription(description); - return this; - } - @Override public ExternalDocumentation getExternalDocs() { return externalDocs; @@ -99,12 +87,6 @@ public void setExternalDocs(ExternalDocumentation externalDocs) { this.externalDocs = externalDocs; } - @Override - public Tag externalDocs(ExternalDocumentation externalDocs) { - setExternalDocs(externalDocs); - return this; - } - public static void merge(org.eclipse.microprofile.openapi.annotations.tags.Tag from, Tag to, boolean override) { if (isAnnotationNull(from)) { return; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java index 88e01c1c7cb..a0202bc73df 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java @@ -194,8 +194,8 @@ public static HttpMethod getHttpMethod(String method) { */ public static Operation getOrCreateOperation(PathItem pathItem, HttpMethod httpMethod) { Operation operation = new OperationImpl(); - if (pathItem.readOperationsMap().get(httpMethod) != null) { - return pathItem.readOperationsMap().get(httpMethod); + if (pathItem.getOperations().get(httpMethod) != null) { + return pathItem.getOperations().get(httpMethod); } switch (httpMethod) { case GET: @@ -231,7 +231,7 @@ public static Operation getOrCreateOperation(PathItem pathItem, HttpMethod httpM public static Operation findOperation(OpenAPI api, Method method, String path) { Operation foundOperation = null; try { - return api.getPaths().get(path).readOperationsMap().get(getHttpMethod(method)); + return api.getPaths().getPathItem(path).getOperations().get(getHttpMethod(method)); } catch (NullPointerException ex) { // Operation not found } @@ -405,7 +405,7 @@ public static boolean isAnnotationNull(Annotation annotation) { return false; } else if (value instanceof Collection && !Collection.class.cast(value).isEmpty()) { return false; - } else if (value instanceof Boolean && Boolean.class.cast(value)) { + } else if (value instanceof Boolean && ((Boolean)value).booleanValue()) { return false; } else if (value.getClass().equals(Class.class) && !Class.class.cast(value).getTypeName().equals("java.lang.Void")) { @@ -427,6 +427,18 @@ public static boolean isAnnotationNull(Annotation annotation) { return allNull; } + public static Boolean mergeProperty(Boolean current, boolean offer, boolean override) { + return mergeProperty(current, Boolean.valueOf(offer), override); + } + + public static Boolean mergeProperty(boolean current, Boolean offer, boolean override) { + return mergeProperty(Boolean.valueOf(current), offer, override); + } + + public static Boolean mergeProperty(boolean current, boolean offer, boolean override) { + return mergeProperty(Boolean.valueOf(current), Boolean.valueOf(offer), override); + } + public static E mergeProperty(E current, E offer, boolean override) { // Treat empty strings as null if (offer instanceof String && offer.toString().isEmpty()) { @@ -547,10 +559,10 @@ public static org.eclipse.microprofile.openapi.models.Operation getOperation(Met OpenAPI api, Map>> resourceMapping) { String path = getResourcePath(method, resourceMapping); if (path != null) { - PathItem pathItem = api.getPaths().get(path); + PathItem pathItem = api.getPaths().getPathItem(path); if (pathItem != null) { PathItem.HttpMethod httpMethod = getHttpMethod(method); - return pathItem.readOperationsMap().get(httpMethod); + return pathItem.getOperations().get(httpMethod); } } return null; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java index eca027ee2a3..35d69500780 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java @@ -321,15 +321,15 @@ public void visitProduces(Produces produces, AnnotatedElement element, ApiContex if (response != null) { // Find the wildcard return type if (response.getContent() != null - && response.getContent().get(javax.ws.rs.core.MediaType.WILDCARD) != null) { - MediaType wildcardMedia = response.getContent().get(javax.ws.rs.core.MediaType.WILDCARD); + && response.getContent().getMediaType(javax.ws.rs.core.MediaType.WILDCARD) != null) { + MediaType wildcardMedia = response.getContent().getMediaType(javax.ws.rs.core.MediaType.WILDCARD); // Copy the wildcard return type to the valid response types for (String mediaType : produces.value()) { - response.getContent().put(getContentType(mediaType), wildcardMedia); + response.getContent().addMediaType(getContentType(mediaType), wildcardMedia); } // If there is an @Produces, remove the wildcard - response.getContent().remove(javax.ws.rs.core.MediaType.WILDCARD); + response.getContent().removeMediaType(javax.ws.rs.core.MediaType.WILDCARD); } } } @@ -340,20 +340,20 @@ public void visitProduces(Produces produces, AnnotatedElement element, ApiContex public void visitConsumes(Consumes consumes, AnnotatedElement element, ApiContext context) { if (element instanceof Method && context.getWorkingOperation() != null) { org.eclipse.microprofile.openapi.models.parameters.RequestBody requestBody = context.getWorkingOperation() - .getRequestBody(); + .getRequestBody(); if (requestBody != null) { // Find the wildcard return type if (requestBody.getContent() != null - && requestBody.getContent().get(javax.ws.rs.core.MediaType.WILDCARD) != null) { - MediaType wildcardMedia = requestBody.getContent().get(javax.ws.rs.core.MediaType.WILDCARD); + && requestBody.getContent().getMediaType(javax.ws.rs.core.MediaType.WILDCARD) != null) { + MediaType wildcardMedia = requestBody.getContent().getMediaType(javax.ws.rs.core.MediaType.WILDCARD); // Copy the wildcard return type to the valid request body types for (String mediaType : consumes.value()) { - requestBody.getContent().put(getContentType(mediaType), wildcardMedia); + requestBody.getContent().addMediaType(getContentType(mediaType), wildcardMedia); } // If there is an @Consumes, remove the wildcard - requestBody.getContent().remove(javax.ws.rs.core.MediaType.WILDCARD); + requestBody.getContent().removeMediaType(javax.ws.rs.core.MediaType.WILDCARD); } } } @@ -367,7 +367,7 @@ public void visitQueryParam(QueryParam param, AnnotatedElement element, ApiConte newParameter.setStyle(Style.SIMPLE); addParameter(element, context, newParameter); } - + @Override public void visitPathParam(PathParam param, AnnotatedElement element, ApiContext context) { org.eclipse.microprofile.openapi.models.parameters.Parameter newParameter = new ParameterImpl(); @@ -377,7 +377,7 @@ public void visitPathParam(PathParam param, AnnotatedElement element, ApiContext newParameter.setStyle(Style.SIMPLE); addParameter(element, context, newParameter); } - + @Override public void visitFormParam(FormParam param, AnnotatedElement element, ApiContext context) { // Find the aggregate schema type of all the parameters @@ -404,8 +404,8 @@ public void visitFormParam(FormParam param, AnnotatedElement element, ApiContext // Set the request body type accordingly. context.getWorkingOperation().getRequestBody().getContent() - .get(javax.ws.rs.core.MediaType.WILDCARD).getSchema() - .setType(formSchemaType); + .getMediaType(javax.ws.rs.core.MediaType.WILDCARD).getSchema() + .setType(formSchemaType); } } @@ -426,7 +426,7 @@ public void visitCookieParam(CookieParam param, AnnotatedElement element, ApiCon newParameter.setStyle(Style.SIMPLE); addParameter(element, context, newParameter); } - + private void addParameter(AnnotatedElement element, ApiContext context, org.eclipse.microprofile.openapi.models.parameters.Parameter newParameter) { SchemaImpl schema = new SchemaImpl(); @@ -469,13 +469,13 @@ private void addParameter(AnnotatedElement element, ApiContext context, } } else { LOGGER.log(SEVERE, "Couldn't add " + newParameter.getIn() + " parameter, \"" + newParameter.getName() - + "\" to the OpenAPI Document. This is usually caused by declaring parameter under a method with " - + "an unsupported annotation."); + + "\" to the OpenAPI Document. This is usually caused by declaring parameter under a method with " + + "an unsupported annotation."); } } } - - private SchemaImpl getArraySchema(AnnotatedElement element) { + + private static SchemaImpl getArraySchema(AnnotatedElement element) { SchemaImpl arraySchema = new SchemaImpl(); ParameterizedType parameterizedType; @@ -490,8 +490,8 @@ private SchemaImpl getArraySchema(AnnotatedElement element) { arraySchema.setType(ModelUtils.getSchemaType((Class) parameterizedType.getActualTypeArguments()[0])); return arraySchema; } - - private String getDefaultValueIfPresent(AnnotatedElement element) { + + private static String getDefaultValueIfPresent(AnnotatedElement element) { Annotation[] annotations = element.getDeclaredAnnotations(); for (Annotation annotation : annotations) { if ("javax.ws.rs.DefaultValue".equals(annotation.annotationType().getName())) { @@ -504,7 +504,7 @@ private String getDefaultValueIfPresent(AnnotatedElement element) { } return null; } - + @Override public void visitOpenAPI(OpenAPIDefinition definition, AnnotatedElement element, ApiContext context) { OpenAPIImpl.merge(definition, context.getApi(), true); @@ -604,7 +604,7 @@ public void visitSchema(Schema schema, AnnotatedElement element, ApiContext cont } // Insert the schema to the request body media type MediaType mediaType = context.getWorkingOperation().getRequestBody().getContent() - .get(javax.ws.rs.core.MediaType.WILDCARD); + .getMediaType(javax.ws.rs.core.MediaType.WILDCARD); SchemaImpl.merge(schema, mediaType.getSchema(), true, context.getApi().getComponents().getSchemas()); if (schema.ref() != null && !schema.ref().isEmpty()) { mediaType.setSchema(new SchemaImpl().ref(schema.ref())); @@ -641,7 +641,7 @@ public void visitOperation(Operation operation, AnnotatedElement element, ApiCon OperationImpl.merge(operation, context.getWorkingOperation(), true); // If the operation should be hidden, remove it if (operation.hidden()) { - ModelUtils.removeOperation(context.getApi().getPaths().get(context.getPath()), + ModelUtils.removeOperation(context.getApi().getPaths().getPathItem(context.getPath()), context.getWorkingOperation()); } } @@ -690,10 +690,10 @@ public void visitAPIResponse(APIResponse apiResponse, AnnotatedElement element, // If the element doesn't also contain a response mapping to the default if (Arrays.asList(element.getDeclaredAnnotationsByType(APIResponse.class)).stream() .noneMatch(a -> a.responseCode() == null || a.responseCode().isEmpty() || a.responseCode() - .equals(org.eclipse.microprofile.openapi.models.responses.APIResponses.DEFAULT))) { + .equals(org.eclipse.microprofile.openapi.models.responses.APIResponses.DEFAULT))) { // Then remove the default response context.getWorkingOperation().getResponses() - .remove(org.eclipse.microprofile.openapi.models.responses.APIResponses.DEFAULT); + .removeAPIResponse(org.eclipse.microprofile.openapi.models.responses.APIResponses.DEFAULT); } } } @@ -732,7 +732,7 @@ public void visitParameter(Parameter parameter, AnnotatedElement element, ApiCon && parameter.in() != ParameterIn.DEFAULT) { // Remove all parameters of the wrong input type matchingMethodParameters - .removeIf(x -> ModelUtils.getParameterType(x) != In.valueOf(parameter.in().name())); + .removeIf(x -> ModelUtils.getParameterType(x) != In.valueOf(parameter.in().name())); } // If there's only one matching parameter, handle it immediately String matchingMethodParamName = ModelUtils.getParameterName(matchingMethodParameters.get(0)); @@ -760,7 +760,7 @@ public void visitParameter(Parameter parameter, AnnotatedElement element, ApiCon mediaType.setSchema(new SchemaImpl()); } mediaType.getSchema() - .setType(ModelUtils.mergeProperty(mediaType.getSchema().getType(), type, false)); + .setType(ModelUtils.mergeProperty(mediaType.getSchema().getType(), type, false)); } } } @@ -863,7 +863,7 @@ public void visitSecurityRequirements(SecurityRequirements securityRequirements, /** * Generates a map listing the location each resource class is mapped to. */ - private Map>> generateResourceMapping(Set> classList) { + private static Map>> generateResourceMapping(Set> classList) { Map>> resourceMapping = new HashMap<>(); for (Class clazz : classList) { if (clazz.isAnnotationPresent(ApplicationPath.class) && Application.class.isAssignableFrom(clazz)) { @@ -952,7 +952,7 @@ private org.eclipse.microprofile.openapi.models.responses.APIResponse insertDefa * @return the {@link javax.ws.rs.core.MediaType} with the given name. Defaults * to WILDCARD. */ - private String getContentType(String name) { + private static String getContentType(String name) { String contentType = javax.ws.rs.core.MediaType.WILDCARD; try { javax.ws.rs.core.MediaType mediaType = javax.ws.rs.core.MediaType.valueOf(name); @@ -1002,11 +1002,10 @@ private org.eclipse.microprofile.openapi.models.media.Schema createSchema(ApiCon schema.setType(null); schema.setItems(null); return schema; - } else { - return createSchema(context, type); - } + } + return createSchema(context, type); } - + /** * Replace the object in the referee with a reference, and create the reference * in the API. diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/BaseProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/BaseProcessor.java index d55ce514174..8c3ca5622f6 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/BaseProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/BaseProcessor.java @@ -46,9 +46,7 @@ import fish.payara.microprofile.openapi.impl.model.servers.ServerImpl; import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.normaliseUrl; import java.net.URL; -import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.eclipse.microprofile.openapi.models.OpenAPI; @@ -105,16 +103,16 @@ public OpenAPI process(OpenAPI api, OpenApiConfiguration config) { String path = normaliseUrl(entry.getKey()); // If the path doesn't exist, create it - if (!api.getPaths().containsKey(path)) { + if (!api.getPaths().hasPathItem(path)) { api.getPaths().addPathItem(path, new PathItemImpl()); } // Clear the current list of servers - api.getPaths().get(path).getServers().clear(); + api.getPaths().getPathItem(path).getServers().clear(); // Add each url for (String serverUrl : entry.getValue()) { - api.getPaths().get(path).addServer(new ServerImpl().url(serverUrl)); + api.getPaths().getPathItem(path).addServer(new ServerImpl().url(serverUrl)); } } } @@ -125,7 +123,7 @@ public OpenAPI process(OpenAPI api, OpenApiConfiguration config) { // Find the matching operation for (PathItem pathItem : api.getPaths().values()) { - for (Operation operation : pathItem.readOperations()) { + for (Operation operation : pathItem.getOperations().values()) { if (operation.getOperationId().equals(entry.getKey())) { // Clear the current list of servers @@ -141,19 +139,13 @@ public OpenAPI process(OpenAPI api, OpenApiConfiguration config) { } } - removeEmptyPaths(api, config); + removeEmptyPaths(api); return api; } - private OpenAPI removeEmptyPaths(OpenAPI api, OpenApiConfiguration config) { - Iterator> it = api.getPaths().entrySet().iterator(); - while (it.hasNext()) { - Map.Entry entry = it.next(); - if (new PathItemImpl().equals(entry.getValue())) { - it.remove(); - } - } - return api; + private static void removeEmptyPaths(OpenAPI api) { + PathItem emptyItem = new PathItemImpl(); + api.getPaths().entrySet().removeIf(entry -> emptyItem.equals(entry.getValue())); } } \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java index ec1b3360ba1..50cc7a506eb 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java @@ -91,9 +91,8 @@ public OpenAPI process(OpenAPI api, OpenApiConfiguration config) { } if (filter != null) { return (OpenAPI) filterObject(api); - } else { - LOGGER.fine("No OASFilter provided."); } + LOGGER.fine("No OASFilter provided."); return api; } @@ -134,7 +133,7 @@ private Object filterObject(Object object) { } for (Object removeTarget : resultsToRemove) { - Iterator iterator = (Iterator) Iterable.class.cast(object).iterator(); + Iterator iterator = Iterable.class.cast(object).iterator(); while (iterator.hasNext()) { if (iterator.next().equals(removeTarget)) { iterator.remove(); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ModelReaderProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ModelReaderProcessor.java index 722d13e7687..72e74cc89dd 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ModelReaderProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ModelReaderProcessor.java @@ -75,9 +75,8 @@ public OpenAPI process(OpenAPI api, OpenApiConfiguration config) { OpenAPI model = reader.buildModel(); if (model != null) { return model; - } else { - LOGGER.log(WARNING, "The OpenAPI model returned by " + reader.getClass().getName() + " was null!"); } + LOGGER.log(WARNING, "The OpenAPI model returned by " + reader.getClass().getName() + " was null!"); } else { LOGGER.fine("No OASModelReader provided."); } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/classloader/ApplicationClassLoader.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/classloader/ApplicationClassLoader.java index e21a5827064..81c7bc88fa5 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/classloader/ApplicationClassLoader.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/classloader/ApplicationClassLoader.java @@ -106,10 +106,10 @@ private byte[] loadClassData(String name) throws IOException { InputStream stream = getClass().getClassLoader().getResourceAsStream(name); int size = stream.available(); byte buff[] = new byte[size]; - DataInputStream in = new DataInputStream(stream); - // Reading the binary data - in.readFully(buff); - in.close(); + try (DataInputStream in = new DataInputStream(stream)) { + // Reading the binary data + in.readFully(buff); + } return buff; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java index f957b941d7c..550efd49ce0 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java @@ -88,20 +88,20 @@ public String getInheritedMediaType() { @Test public void inheritedMediaTypeTest() { - APIResponses responses = document.getPaths().get("/test/response").getGET().getResponses(); + APIResponses responses = document.getPaths().getPathItem("/test/response").getGET().getResponses(); // Test the default response doesn't exist - assertNull("The default response should be removed when not used.", responses.getDefault()); + assertNull("The default response should be removed when not used.", responses.getDefaultValue()); // Test the 200 response - assertNotNull("The 200 response should have been created.", responses.get("200")); + assertNotNull("The 200 response should have been created.", responses.getAPIResponse("200")); assertNotNull("The 200 response should return application/json.", - responses.get("200").getContent().get(APPLICATION_JSON)); + responses.getAPIResponse("200").getContent().getMediaType(APPLICATION_JSON)); assertEquals("The 200 response application/json should match the specified schema.", "hello!", - responses.get("200").getContent().get(APPLICATION_JSON).getSchema().getDescription()); + responses.getAPIResponse("200").getContent().getMediaType(APPLICATION_JSON).getSchema().getDescription()); assertNotNull("The 200 response should return application/xml.", - responses.get("200").getContent().get(APPLICATION_XML)); + responses.getAPIResponse("200").getContent().getMediaType(APPLICATION_XML)); assertEquals("The 200 response application/xml should match the specified schema.", "hello!", - responses.get("200").getContent().get(APPLICATION_XML).getSchema().getDescription()); + responses.getAPIResponse("200").getContent().getMediaType(APPLICATION_XML).getSchema().getDescription()); } } \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java index 8e5676a1c29..0e4b48f0b68 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java @@ -77,8 +77,8 @@ public String getRoot() { @Test public void testRoot() { - assertNotNull("The root resource wasn't found.", document.getPaths().get("/test")); + assertNotNull("The root resource wasn't found.", document.getPaths().getPathItem("/test")); assertEquals("The root resource had the wrong origin.", "getRoot", - document.getPaths().get("/test").getGET().getOperationId()); + document.getPaths().getPathItem("/test").getGET().getOperationId()); } } \ No newline at end of file diff --git a/appserver/pom.xml b/appserver/pom.xml index bed2fad11ed..8c4fbb2093e 100644 --- a/appserver/pom.xml +++ b/appserver/pom.xml @@ -206,7 +206,7 @@ 1.0.payara-p1 1.1.payara-p1 1.1-payara-p1 - 1.0 + 1.1.1 5.4 1.2.payara-p2 From 247b10b08ed5c85999df8513e1995d965a3846bc Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Mon, 11 Mar 2019 09:29:00 +0000 Subject: [PATCH 010/108] Added missing name change - missed from prior commit --- appserver/ejb/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appserver/ejb/pom.xml b/appserver/ejb/pom.xml index 08a30b5e544..86b5e92bec4 100755 --- a/appserver/ejb/pom.xml +++ b/appserver/ejb/pom.xml @@ -63,7 +63,7 @@ ejb-full-container ejb-timer-databases ejb-timer-service-app - ejb-rest-remoting + ejb-http-remoting ejb-connector-l10n ejb-container-l10n From 3229892506f4b7336219078c7741e40adc4d5282 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Mon, 11 Mar 2019 16:07:06 +0100 Subject: [PATCH 011/108] PAYARA-3466 new properties and fixes --- .../openapi/impl/model/ExtensibleImpl.java | 30 ++- ...kedHashMap.java => ExtensibleTreeMap.java} | 10 +- .../openapi/impl/model/PathItemImpl.java | 11 +- .../openapi/impl/model/PathsImpl.java | 4 +- .../impl/model/callbacks/CallbackImpl.java | 6 +- .../openapi/impl/model/media/ContentImpl.java | 3 + .../model/responses/APIResponsesImpl.java | 4 +- .../impl/model/security/ScopesImpl.java | 6 +- .../impl/model/servers/ServerImpl.java | 12 +- .../model/servers/ServerVariablesImpl.java | 4 +- .../impl/processor/ApplicationProcessor.java | 179 +++++++++--------- appserver/pom.xml | 2 +- 12 files changed, 153 insertions(+), 118 deletions(-) rename appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/{ExtensibleLinkedHashMap.java => ExtensibleTreeMap.java} (74%) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index 6c6db641ffa..9925f306cf9 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -42,13 +42,20 @@ import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.isAnnotationNull; import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.mergeProperty; +import java.io.IOException; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; +import javax.json.Json; + import org.eclipse.microprofile.openapi.annotations.extensions.Extension; import org.eclipse.microprofile.openapi.models.Extensible; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.ObjectMapper; + public abstract class ExtensibleImpl> implements Extensible { protected Map extensions = new HashMap<>(); @@ -83,16 +90,33 @@ public static void merge(Extension from, Extensible to, boolean override) { to.setExtensions(new LinkedHashMap<>()); } if (from.name() != null && !from.name().isEmpty()) { - Object value = mergeProperty(to.getExtensions().get(from.name()), convertExtensionValue(from.value()), - override); + Object value = mergeProperty(to.getExtensions().get(from.name()), + convertExtensionValue(from.value(), from.parseValue()), override); to.getExtensions().put(from.name(), value); } } - public static Object convertExtensionValue(String value) { + public static Object convertExtensionValue(String value, boolean parseValue) { if (value == null) { return null; } + if (parseValue) { + if (value.startsWith("{") || value.startsWith("[")) { // JSON object + array + try { + return new ObjectMapper().readTree(value); + } catch (Exception e) { + return value; + } + } + if ("true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value)) { + return Boolean.valueOf(value); + } + // must be number + if (value.indexOf('.') >= 0) { + return Double.valueOf(value); + } + return Long.valueOf(value); + } // Could be an array if (value.contains(",")) { // Remove leading and trailing brackets, then parse to an array diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleLinkedHashMap.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java similarity index 74% rename from appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleLinkedHashMap.java rename to appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java index 477307e6d5d..fecd5fd6445 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleLinkedHashMap.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java @@ -1,21 +1,21 @@ package fish.payara.microprofile.openapi.impl.model; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Map; +import java.util.TreeMap; import org.eclipse.microprofile.openapi.models.Extensible; -public abstract class ExtensibleLinkedHashMap> extends LinkedHashMap -implements Extensible { +public abstract class ExtensibleTreeMap> extends TreeMap + implements Extensible { protected Map extensions = new HashMap<>(); - protected ExtensibleLinkedHashMap() { + protected ExtensibleTreeMap() { super(); } - protected ExtensibleLinkedHashMap(Map items) { + protected ExtensibleTreeMap(Map items) { super(items); } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java index e06c2e7fb3a..41cf49d074e 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java @@ -178,16 +178,7 @@ public void setTRACE(Operation trace) { @Override public Map getOperations() { - EnumMap operations = new EnumMap<>(HttpMethod.class); - operations.put(HttpMethod.DELETE, delete); - operations.put(HttpMethod.GET, get); - operations.put(HttpMethod.HEAD, head); - operations.put(HttpMethod.OPTIONS, options); - operations.put(HttpMethod.PATCH, patch); - operations.put(HttpMethod.POST, post); - operations.put(HttpMethod.PUT, put); - operations.put(HttpMethod.TRACE, trace); - return operations; + return readOperationsMap(); } @Override diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java index e49c65435b7..0fb24e1bb78 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java @@ -46,7 +46,7 @@ import fish.payara.microprofile.openapi.impl.model.util.ModelUtils; -public class PathsImpl extends ExtensibleLinkedHashMap implements Paths { +public class PathsImpl extends ExtensibleTreeMap implements Paths { private static final long serialVersionUID = -3876996963579977405L; @@ -54,7 +54,7 @@ public PathsImpl() { super(); } - public PathsImpl(Map items) { + public PathsImpl(Map items) { super(items); } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java index 93bc3e8f437..d115314e180 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java @@ -53,11 +53,11 @@ import org.eclipse.microprofile.openapi.models.callbacks.Callback; import org.eclipse.microprofile.openapi.models.media.Schema; -import fish.payara.microprofile.openapi.impl.model.ExtensibleLinkedHashMap; +import fish.payara.microprofile.openapi.impl.model.ExtensibleTreeMap; import fish.payara.microprofile.openapi.impl.model.OperationImpl; import fish.payara.microprofile.openapi.impl.model.PathItemImpl; -public class CallbackImpl extends ExtensibleLinkedHashMap implements Callback { +public class CallbackImpl extends ExtensibleTreeMap implements Callback { private static final long serialVersionUID = 5549098533131353142L; @@ -67,7 +67,7 @@ public CallbackImpl() { super(); } - public CallbackImpl(Map items) { + public CallbackImpl(Map items) { super(items); } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java index 0ee319ee614..7e2540e1aae 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java @@ -111,6 +111,9 @@ public static void merge(org.eclipse.microprofile.openapi.annotations.media.Cont for (ExampleObject example : from.examples()) { ExampleImpl.merge(example, to.getMediaType(typeName).getExamples(), override); } + if (!from.example().isEmpty()) { + to.getMediaType(typeName).setExample(from.example()); + } // Merge schema if (!isAnnotationNull(from.schema())) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java index b2f800b3878..0a30fb4082f 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java @@ -48,9 +48,9 @@ import org.eclipse.microprofile.openapi.models.responses.APIResponse; import org.eclipse.microprofile.openapi.models.responses.APIResponses; -import fish.payara.microprofile.openapi.impl.model.ExtensibleLinkedHashMap; +import fish.payara.microprofile.openapi.impl.model.ExtensibleTreeMap; -public class APIResponsesImpl extends ExtensibleLinkedHashMap +public class APIResponsesImpl extends ExtensibleTreeMap implements APIResponses { private static final long serialVersionUID = 2811935761440110541L; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java index 1ed1852075f..d0ff158c036 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java @@ -43,9 +43,9 @@ import org.eclipse.microprofile.openapi.models.security.Scopes; -import fish.payara.microprofile.openapi.impl.model.ExtensibleLinkedHashMap; +import fish.payara.microprofile.openapi.impl.model.ExtensibleTreeMap; -public class ScopesImpl extends ExtensibleLinkedHashMap implements Scopes { +public class ScopesImpl extends ExtensibleTreeMap implements Scopes { private static final long serialVersionUID = -615440059031779085L; @@ -53,7 +53,7 @@ public ScopesImpl() { super(); } - public ScopesImpl(Map scopes) { + public ScopesImpl(Map scopes) { super(scopes); } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java index c32d9d2c264..14bdf340c38 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java @@ -44,10 +44,16 @@ import java.util.Map; +import javax.json.bind.annotation.JsonbProperty; +import javax.xml.bind.annotation.XmlTransient; + import org.eclipse.microprofile.openapi.models.servers.Server; import org.eclipse.microprofile.openapi.models.servers.ServerVariable; import org.eclipse.microprofile.openapi.models.servers.ServerVariables; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; public class ServerImpl extends ExtensibleImpl implements Server { @@ -78,14 +84,18 @@ public void setDescription(String description) { @Override public ServerVariables getVariables() { - return variables instanceof ServerVariables ? (ServerVariables) variables : new ServerVariablesImpl(variables); + return variables instanceof ServerVariables || variables == null + ? (ServerVariables) variables + : new ServerVariablesImpl(variables); } + @JsonIgnore @Override public void setVariables(ServerVariables variables) { this.variables = variables; } + @JsonProperty("variables") @Override public void setVariables(Map variables) { this.variables = variables; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java index ee22abd091c..6e2b9d31a34 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java @@ -48,9 +48,9 @@ import org.eclipse.microprofile.openapi.models.servers.ServerVariable; import org.eclipse.microprofile.openapi.models.servers.ServerVariables; -import fish.payara.microprofile.openapi.impl.model.ExtensibleLinkedHashMap; +import fish.payara.microprofile.openapi.impl.model.ExtensibleTreeMap; -public class ServerVariablesImpl extends ExtensibleLinkedHashMap implements ServerVariables { +public class ServerVariablesImpl extends ExtensibleTreeMap implements ServerVariables { private static final long serialVersionUID = 8869393484826870024L; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java index 35d69500780..71234583e9f 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java @@ -513,111 +513,118 @@ public void visitOpenAPI(OpenAPIDefinition definition, AnnotatedElement element, @Override public void visitSchema(Schema schema, AnnotatedElement element, ApiContext context) { if (element instanceof Class) { + visitSchemaClass(schema, (Class) element, context); + } + if (element instanceof Field) { + visitSchemaField(schema, (Field) element, context); + } + if (element instanceof java.lang.reflect.Parameter) { + visitSchemaParameter(schema, (java.lang.reflect.Parameter) element, context); + } + } - // Get the schema object name - String schemaName = (schema == null) ? null : schema.name(); - if (schemaName == null || schemaName.isEmpty()) { - schemaName = Class.class.cast(element).getSimpleName(); - } + private void visitSchemaClass(Schema schema, Class clazz, ApiContext context) { + // Get the schema object name + String schemaName = (schema == null) ? null : schema.name(); + if (schemaName == null || schemaName.isEmpty()) { + schemaName = clazz.getSimpleName(); + } - // Add a new schema - org.eclipse.microprofile.openapi.models.media.Schema newSchema = new SchemaImpl(); - context.getApi().getComponents().addSchema(schemaName, newSchema); + // Add a new schema + org.eclipse.microprofile.openapi.models.media.Schema newSchema = new SchemaImpl(); + context.getApi().getComponents().addSchema(schemaName, newSchema); - // If there is an annotation - if (schema != null) { - SchemaImpl.merge(schema, newSchema, true, context.getApi().getComponents().getSchemas()); - } else { - newSchema.setType(SchemaType.OBJECT); - Map fields = new LinkedHashMap<>(); - for (Field field : Class.class.cast(element).getDeclaredFields()) { - if (!Modifier.isTransient(field.getModifiers())) { - fields.put(field.getName(), createSchema(context, element, field.getType())); - } + // If there is an annotation + if (schema != null) { + SchemaImpl.merge(schema, newSchema, true, context.getApi().getComponents().getSchemas()); + } else { + newSchema.setType(SchemaType.OBJECT); + Map fields = new LinkedHashMap<>(); + for (Field field : clazz.getDeclaredFields()) { + if (!Modifier.isTransient(field.getModifiers())) { + fields.put(field.getName(), createSchema(context, clazz, field.getType())); } - newSchema.setProperties(fields); } + newSchema.setProperties(fields); + } - // If there is an extending class, add the data - if (Class.class.cast(element).getSuperclass() != null) { - Class superClass = Class.class.cast(element).getSuperclass(); - - // If the super class is legitimate - if (!superClass.equals(Object.class)) { + // If there is an extending class, add the data + if (clazz.getSuperclass() != null) { + Class superClass = clazz.getSuperclass(); - // Get the parent schema annotation - Schema parentSchema = superClass.getDeclaredAnnotation(Schema.class); + // If the super class is legitimate + if (!superClass.equals(Object.class)) { - // Create a schema for the parent - visitSchema(parentSchema, superClass, context); + // Get the parent schema annotation + Schema parentSchema = superClass.getDeclaredAnnotation(Schema.class); - // Get the superclass schema name - String parentSchemaName = (parentSchema == null) ? null : parentSchema.name(); - if (parentSchemaName == null || parentSchemaName.isEmpty()) { - parentSchemaName = Class.class.cast(superClass).getSimpleName(); - } + // Create a schema for the parent + visitSchema(parentSchema, superClass, context); - // Link the schemas - newSchema.addAllOf(new SchemaImpl().ref(parentSchemaName)); + // Get the superclass schema name + String parentSchemaName = (parentSchema == null) ? null : parentSchema.name(); + if (parentSchemaName == null || parentSchemaName.isEmpty()) { + parentSchemaName = superClass.getSimpleName(); } + + // Link the schemas + newSchema.addAllOf(new SchemaImpl().ref(parentSchemaName)); } } - if (element instanceof Field) { + } - // Get the schema object name - String schemaName = schema.name(); - if (schemaName == null || schemaName.isEmpty()) { - schemaName = Field.class.cast(element).getName(); - } + private void visitSchemaField(Schema schema, Field field, ApiContext context) { + // Get the schema object name + String schemaName = schema.name(); + if (schemaName == null || schemaName.isEmpty()) { + schemaName = field.getName(); + } - // Get the parent schema object name - String parentName = null; - if (Field.class.cast(element).getDeclaringClass().isAnnotationPresent(Schema.class)) { - parentName = Field.class.cast(element).getDeclaringClass().getDeclaredAnnotation(Schema.class).name(); - } - if (parentName == null || parentName.isEmpty()) { - parentName = Field.class.cast(element).getDeclaringClass().getSimpleName(); - } + // Get the parent schema object name + String parentName = null; + if (field.getDeclaringClass().isAnnotationPresent(Schema.class)) { + parentName = field.getDeclaringClass().getDeclaredAnnotation(Schema.class).name(); + } + if (parentName == null || parentName.isEmpty()) { + parentName = field.getDeclaringClass().getSimpleName(); + } - // Get or create the parent schema object - org.eclipse.microprofile.openapi.models.media.Schema parent = context.getApi().getComponents().getSchemas() - .getOrDefault(parentName, new SchemaImpl()); - context.getApi().getComponents().getSchemas().put(parentName, parent); + // Get or create the parent schema object + org.eclipse.microprofile.openapi.models.media.Schema parent = context.getApi().getComponents().getSchemas() + .getOrDefault(parentName, new SchemaImpl()); + context.getApi().getComponents().getSchemas().put(parentName, parent); - org.eclipse.microprofile.openapi.models.media.Schema property = new SchemaImpl(); - parent.addProperty(schemaName, property); - property.setType(ModelUtils.getSchemaType(Field.class.cast(element).getType())); - SchemaImpl.merge(schema, property, true, context.getApi().getComponents().getSchemas()); - } - if (element instanceof java.lang.reflect.Parameter) { + org.eclipse.microprofile.openapi.models.media.Schema property = new SchemaImpl(); + parent.addProperty(schemaName, property); + property.setType(ModelUtils.getSchemaType(field.getType())); + SchemaImpl.merge(schema, property, true, context.getApi().getComponents().getSchemas()); + } - // If this is being parsed at the start, ignore it as the path doesn't exist - if (context.getWorkingOperation() == null) { - return; + private void visitSchemaParameter(Schema schema, java.lang.reflect.Parameter parameter, ApiContext context) { + // If this is being parsed at the start, ignore it as the path doesn't exist + if (context.getWorkingOperation() == null) { + return; + } + // Check if it's a request body + if (ModelUtils.isRequestBody(parameter)) { + if (context.getWorkingOperation().getRequestBody() == null) { + context.getWorkingOperation().setRequestBody(new RequestBodyImpl()); } - - java.lang.reflect.Parameter parameter = (java.lang.reflect.Parameter) element; - // Check if it's a request body - if (ModelUtils.isRequestBody(parameter)) { - if (context.getWorkingOperation().getRequestBody() == null) { - context.getWorkingOperation().setRequestBody(new RequestBodyImpl()); - } - // Insert the schema to the request body media type - MediaType mediaType = context.getWorkingOperation().getRequestBody().getContent() - .getMediaType(javax.ws.rs.core.MediaType.WILDCARD); - SchemaImpl.merge(schema, mediaType.getSchema(), true, context.getApi().getComponents().getSchemas()); - if (schema.ref() != null && !schema.ref().isEmpty()) { - mediaType.setSchema(new SchemaImpl().ref(schema.ref())); - } - } else if (ModelUtils.getParameterType(parameter) != null) { - for (org.eclipse.microprofile.openapi.models.parameters.Parameter param : context.getWorkingOperation() - .getParameters()) { - if (param.getName().equals(ModelUtils.getParameterName(parameter))) { - SchemaImpl.merge(schema, param.getSchema(), true, - context.getApi().getComponents().getSchemas()); - if (schema.ref() != null && !schema.ref().isEmpty()) { - param.setSchema(new SchemaImpl().ref(schema.ref())); - } + // Insert the schema to the request body media type + MediaType mediaType = context.getWorkingOperation().getRequestBody().getContent() + .getMediaType(javax.ws.rs.core.MediaType.WILDCARD); + SchemaImpl.merge(schema, mediaType.getSchema(), true, context.getApi().getComponents().getSchemas()); + if (schema.ref() != null && !schema.ref().isEmpty()) { + mediaType.setSchema(new SchemaImpl().ref(schema.ref())); + } + } else if (ModelUtils.getParameterType(parameter) != null) { + for (org.eclipse.microprofile.openapi.models.parameters.Parameter param : context.getWorkingOperation() + .getParameters()) { + if (param.getName().equals(ModelUtils.getParameterName(parameter))) { + SchemaImpl.merge(schema, param.getSchema(), true, + context.getApi().getComponents().getSchemas()); + if (schema.ref() != null && !schema.ref().isEmpty()) { + param.setSchema(new SchemaImpl().ref(schema.ref())); } } } diff --git a/appserver/pom.xml b/appserver/pom.xml index 8c4fbb2093e..a9154e1291f 100644 --- a/appserver/pom.xml +++ b/appserver/pom.xml @@ -206,7 +206,7 @@ 1.0.payara-p1 1.1.payara-p1 1.1-payara-p1 - 1.1.1 + 1.1.2 5.4 1.2.payara-p2 From aa139054b20cb77da81f121592def1bb57e376df Mon Sep 17 00:00:00 2001 From: Sven Diedrichsen Date: Mon, 11 Mar 2019 20:21:36 +0100 Subject: [PATCH 012/108] Adding NULL check to prevent NPE when calling isTraditionalClusterActive --- .../iiop/impl/IiopFolbGmsClient.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IiopFolbGmsClient.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IiopFolbGmsClient.java index 5d7efdb39b3..a2811a08315 100644 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IiopFolbGmsClient.java +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IiopFolbGmsClient.java @@ -100,12 +100,12 @@ public class IiopFolbGmsClient implements ClusterListener { private Map currentMembers; private GroupInfoService gis; - + private PayaraCluster cluster; - + private static final String USE_NODE_HOST_FOR_LOCAL_NODE_PROPERTY = "useNodeHostForLocalNode"; - - private static final String USE_NODE_HOST_FOR_LOCAL_NODE_SYSTEM_PROPERTY = "fish.payara.iiop.gmsClient." + + private static final String USE_NODE_HOST_FOR_LOCAL_NODE_SYSTEM_PROPERTY = "fish.payara.iiop.gmsClient." + USE_NODE_HOST_FOR_LOCAL_NODE_PROPERTY; private void fineLog( String fmt, Object... args ) { @@ -195,13 +195,13 @@ public boolean isGMSAvailable() { // // Implementation // - + private boolean isDeploymentGroupsActive() { return cluster != null && cluster.isEnabled() && cluster.getClusterMembers().size() > 1; } - + private boolean isTraditionalClusterActive() { - return myServer.getCluster() != null; + return myServer != null && myServer.getCluster() != null; } private void removeMember(final String signal) @@ -247,7 +247,7 @@ private void addMember(final String signal) fineLog( "IiopFolbGmsClient.addMember: {0} already present: no action", instanceName); } else { - ClusterInstanceInfo clusterInstanceInfo = + ClusterInstanceInfo clusterInstanceInfo = getClusterInstanceInfo(instanceName) ; currentMembers.put( clusterInstanceInfo.name(), @@ -261,7 +261,7 @@ private void addMember(final String signal) fineLog( "IiopFolbGmsClient.addMember: {0} - notification complete", instanceName); } - } + } } finally { fineLog( "IiopFolbGmsClient.addMember<-: {0}", instanceName); } @@ -305,15 +305,15 @@ private ClusterInstanceInfo getClusterInstanceInfo( Server server, final IiopService iservice = config.getExtensionByType(IiopService.class) ; fineLog( "getClusterInstanceInfo: iservice {0}", iservice ) ; - + final String nodeName = server.getNodeRef() ; String hostName = nodeName ; if (nodes != null) { Node node = nodes.getNode( nodeName ) ; if (node != null) { - // If this is the local node, and the useNodeHostForLocalNode property has not been set at the ORB or + // If this is the local node, and the useNodeHostForLocalNode property has not been set at the ORB or // System level, use the local host name - if ((node.isLocal() && !Boolean.getBoolean(USE_NODE_HOST_FOR_LOCAL_NODE_SYSTEM_PROPERTY)) + if ((node.isLocal() && !Boolean.getBoolean(USE_NODE_HOST_FOR_LOCAL_NODE_SYSTEM_PROPERTY)) && (node.isLocal() && !Boolean.parseBoolean(iservice.getOrb().getPropertyValue( USE_NODE_HOST_FOR_LOCAL_NODE_PROPERTY, "false")))) { try { @@ -452,7 +452,7 @@ public void memberRemoved(MemberEvent event) { class GroupInfoServiceGMSImpl extends GroupInfoServiceBase { @Override - public List internalClusterInstanceInfo( + public List internalClusterInstanceInfo( List endpoints) { fineLog( "internalClusterInstanceInfo: currentMembers {0}", From 0efac48671eb52fab364237237108393e7cd5d03 Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Tue, 12 Mar 2019 10:45:07 +0100 Subject: [PATCH 013/108] PAYARA-3444: Refactoring set command part 1 - Set Property early exits --- .../sun/enterprise/v3/admin/SetCommand.java | 166 +++++++++--------- 1 file changed, 87 insertions(+), 79 deletions(-) diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java index 528cbff6f18..d061efd8812 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java @@ -324,89 +324,12 @@ private boolean set(AdminCommandContext context, SetOperation op) { pattern = target.substring(0, trueLastIndexOf(target, '.')); if (pattern.endsWith("property")) { // need to find the right parent. - Dom parentNode = null; if ("property".equals(pattern)) { // we are setting domain properties as there is no previous pattern // create and set the property - try { - final String fname = attrName; - final String fvalue = value; - ConfigSupport.apply(new SingleConfigCode() { - @Override - public Object run(Domain domain) throws PropertyVetoException, TransactionFailure { - Property p = domain.createChild(Property.class); - p.setName(fname); - p.setValue(fvalue); - domain.getProperty().add(p); - return p; - } - },domain); - success(context, targetName, value); - runLegacyChecks(context); - if (targetService.isThisDAS() && !replicateSetCommand(context, target, value)) { - return false; - } - return true; - } catch (TransactionFailure transactionFailure) { - //fail(context, "Could not change the attributes: " + - // transactionFailure.getMessage(), transactionFailure); - fail(context, localStrings.getLocalString("admin.set.attribute.change.failure", "Could not change the attributes: {0}", - transactionFailure.getMessage()), transactionFailure); - return false; - } - + return setDomainProperty(context, op, targetName); } else { - pattern = pattern.substring(0, trueLastIndexOf(pattern, '.')); - parentNodes = getAliasedParent(domain, pattern); - } - pattern = parentNodes[0].relativeName; - matchingNodes = getMatchingNodes(dottedNames, pattern); - if (matchingNodes.isEmpty()) { - //fail(context, "No configuration found for " + targetName); - fail(context, localStrings.getLocalString("admin.set.configuration.notfound", "No configuration found for {0}", targetName)); - return false; - } - for (Map.Entry node : matchingNodes.entrySet()) { - if (node.getValue().equals(pattern)) { - parentNode = node.getKey(); - } - } - if (parentNode == null) { - //fail(context, "No configuration found for " + targetName); - fail(context, localStrings.getLocalString("admin.set.configuration.notfound", "No configuration found for {0}", targetName)); - return false; - } - - if (value == null || value.length() == 0) { - // setting to the empty string means to remove the property, so don't create it - success(context, targetName, value); - return true; - } - // create and set the property - Map attributes = new HashMap(); - attributes.put("value", value); - attributes.put("name", attrName); - try { - if (!(parentNode instanceof ConfigBean)) { - final ClassCastException cce = new ClassCastException(parentNode.getClass().getName()); - fail(context, localStrings.getLocalString("admin.set.attribute.change.failure", - "Could not change the attributes: {0}", - cce.getMessage(), cce)); - return false; - } - ConfigSupport.createAndSet((ConfigBean) parentNode, Property.class, attributes); - success(context, targetName, value); - runLegacyChecks(context); - if (targetService.isThisDAS() && !replicateSetCommand(context, target, value)) { - return false; - } - return true; - } catch (TransactionFailure transactionFailure) { - //fail(context, "Could not change the attributes: " + - // transactionFailure.getMessage(), transactionFailure); - fail(context, localStrings.getLocalString("admin.set.attribute.change.failure", "Could not change the attributes: {0}", - transactionFailure.getMessage()), transactionFailure); - return false; + return setProperty(context, pattern, op, targetName, dottedNames); } } } @@ -533,6 +456,91 @@ public Object run(Domain domain) throws PropertyVetoException, TransactionFailur return true; } + + private boolean setDomainProperty(AdminCommandContext context, SetOperation op, String targetName) { + try { + final String fname = op.attrName; + final String fvalue = op.value; + ConfigSupport.apply(new SingleConfigCode() { + @Override + public Object run(Domain domain) throws PropertyVetoException, TransactionFailure { + Property p = domain.createChild(Property.class); + p.setName(fname); + p.setValue(fvalue); + domain.getProperty().add(p); + return p; + } + },domain); + return replicatePropertyChange(context, op, targetName); + } catch (TransactionFailure transactionFailure) { + //fail(context, "Could not change the attributes: " + + // transactionFailure.getMessage(), transactionFailure); + fail(context, localStrings.getLocalString("admin.set.attribute.change.failure", "Could not change the attributes: {0}", + transactionFailure.getMessage()), transactionFailure); + return false; + } + } + + private boolean setProperty(AdminCommandContext context, String pattern, SetOperation op, String targetName, Map dottedNames) { + Dom parentNode = null; + pattern = pattern.substring(0, trueLastIndexOf(pattern, '.')); + TreeNode[] parentNodes_ = getAliasedParent(domain, pattern); + + pattern = parentNodes_[0].relativeName; + Map matchingNodes_ = getMatchingNodes(dottedNames, pattern); + if (matchingNodes_.isEmpty()) { + //fail(context, "No configuration found for " + targetName); + fail(context, localStrings.getLocalString("admin.set.configuration.notfound", "No configuration found for {0}", targetName)); + return false; + } + for (Map.Entry node : matchingNodes_.entrySet()) { + if (node.getValue().equals(pattern)) { + parentNode = node.getKey(); + } + } + if (parentNode == null) { + //fail(context, "No configuration found for " + targetName); + fail(context, localStrings.getLocalString("admin.set.configuration.notfound", "No configuration found for {0}", targetName)); + return false; + } + + if (op.value == null || op.value.length() == 0) { + // setting to the empty string means to remove the property, so don't create it + success(context, targetName, op.value); + return true; + } + // create and set the property + Map attributes = new HashMap(); + attributes.put("value", op.value); + attributes.put("name", op.attrName); + try { + if (!(parentNode instanceof ConfigBean)) { + final ClassCastException cce = new ClassCastException(parentNode.getClass().getName()); + fail(context, localStrings.getLocalString("admin.set.attribute.change.failure", + "Could not change the attributes: {0}", + cce.getMessage(), cce)); + return false; + } + ConfigSupport.createAndSet((ConfigBean) parentNode, Property.class, attributes); + return replicatePropertyChange(context, op, targetName); + } catch (TransactionFailure transactionFailure) { + //fail(context, "Could not change the attributes: " + + // transactionFailure.getMessage(), transactionFailure); + fail(context, localStrings.getLocalString("admin.set.attribute.change.failure", "Could not change the attributes: {0}", + transactionFailure.getMessage()), transactionFailure); + return false; + } + } + + private boolean replicatePropertyChange(AdminCommandContext context, SetOperation op, String targetName) { + success(context, targetName, op.value); + runLegacyChecks(context); + if (targetService.isThisDAS() && !replicateSetCommand(context, op.target, op.value)) { + return false; + } + return true; + } + public static void setLeafElement( final ConfigBean node, final String elementName, From 8a30d084a8dae403792de4155c11d7346add9954 Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Tue, 12 Mar 2019 11:06:41 +0100 Subject: [PATCH 014/108] PAYARA-3444: Refactoring set command part 2 - Other property early exits --- .../sun/enterprise/v3/admin/SetCommand.java | 59 +++++++++++-------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java index d061efd8812..ee1fd0899e8 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java @@ -336,8 +336,6 @@ private boolean set(AdminCommandContext context, SetOperation op) { Map> changes = new HashMap>(); - boolean setElementSuccess = false; - boolean delPropertySuccess = false; boolean delProperty = false; Map attrChanges = new HashMap(); if (isProperty) { @@ -383,20 +381,9 @@ private boolean set(AdminCommandContext context, SetOperation op) { if (trueLastIndexOf(str, '.') != -1) { str = str.substring(trueLastIndexOf(str, '.') + 1); } - try { if (str != null) { - ConfigSupport.deleteChild((ConfigBean) targetNode.parent(), (ConfigBean) targetNode); - delPropertySuccess = true; + return deleteProperty(context, op, targetName, targetNode); } - } catch (IllegalArgumentException ie) { - fail(context, localStrings.getLocalString("admin.set.delete.property.failure", "Could not delete the property: {0}", - ie.getMessage()), ie); - return false; - } catch (TransactionFailure transactionFailure) { - fail(context, localStrings.getLocalString("admin.set.attribute.change.failure", "Could not change the attributes: {0}", - transactionFailure.getMessage()), transactionFailure); - return false; - } } else { changes.put((ConfigBean) node.getKey(), attrChanges); } @@ -414,15 +401,7 @@ private boolean set(AdminCommandContext context, SetOperation op) { warning(context, localStrings.getLocalString("admin.set.elementdeprecated", "Warning: The element {0} is deprecated.", finalDottedName)); } - try { - setLeafElement((ConfigBean) targetNode, name, value); - } catch (TransactionFailure ex) { - fail(context, localStrings.getLocalString("admin.set.badelement", "Cannot change the element: {0}", - ex.getMessage()), ex); - return false; - } - setElementSuccess = true; - break; + return setAttribute(context, op, targetName, (ConfigBean) targetNode, name); } } } @@ -441,8 +420,6 @@ private boolean set(AdminCommandContext context, SetOperation op) { return false; } - } else if (delPropertySuccess || setElementSuccess) { - success(context, targetName, value); } else { fail(context, localStrings.getLocalString("admin.set.configuration.notfound", "No configuration found for {0}", targetName)); return false; @@ -533,8 +510,38 @@ private boolean setProperty(AdminCommandContext context, String pattern, SetOper } private boolean replicatePropertyChange(AdminCommandContext context, SetOperation op, String targetName) { - success(context, targetName, op.value); runLegacyChecks(context); + return replicatePropertyChangeWithoutLegacyChecks(context, op, targetName); + } + + private boolean deleteProperty(AdminCommandContext context, SetOperation op, String targetName, Dom targetNode) { + try { + ConfigSupport.deleteChild((ConfigBean) targetNode.parent(), (ConfigBean) targetNode); + return replicatePropertyChangeWithoutLegacyChecks(context, op, targetName); + } catch (IllegalArgumentException ie) { + fail(context, localStrings.getLocalString("admin.set.delete.property.failure", "Could not delete the property: {0}", + ie.getMessage()), ie); + return false; + } catch (TransactionFailure transactionFailure) { + fail(context, localStrings.getLocalString("admin.set.attribute.change.failure", "Could not change the attributes: {0}", + transactionFailure.getMessage()), transactionFailure); + return false; + } + } + + private boolean setAttribute(AdminCommandContext context, SetOperation op, String targetName, ConfigBean targetNode, String name) { + try { + setLeafElement(targetNode, name, op.value); + } catch (TransactionFailure ex) { + fail(context, localStrings.getLocalString("admin.set.badelement", "Cannot change the element: {0}", + ex.getMessage()), ex); + return false; + } + return replicatePropertyChangeWithoutLegacyChecks(context, op, targetName); + } + + private boolean replicatePropertyChangeWithoutLegacyChecks(AdminCommandContext context, SetOperation op, String targetName) { + success(context, targetName, op.value); if (targetService.isThisDAS() && !replicateSetCommand(context, op.target, op.value)) { return false; } From 545d6bc15855eaec27bb8b17276c3a650d57daf3 Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Tue, 12 Mar 2019 11:20:51 +0100 Subject: [PATCH 015/108] PAYARA-3444: Refactoring set command part 3 - Separate node matching and change collection --- .../sun/enterprise/v3/admin/SetCommand.java | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java index ee1fd0899e8..5aba702cc36 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java @@ -266,10 +266,6 @@ private boolean prepare(AdminCommandContext context, String nameval) { private boolean set(AdminCommandContext context, SetOperation op) { String pattern = op.pattern; - String value = op.value; - String target = op.target; - String attrName = op.attrName; - boolean isProperty = op.isProperty; // now // first let's get the parent for this pattern. @@ -321,7 +317,7 @@ private boolean set(AdminCommandContext context, SetOperation op) { if (matchingNodes.isEmpty()) { // it's possible they are trying to create a property object.. lets check this. // strip out the property name - pattern = target.substring(0, trueLastIndexOf(target, '.')); + pattern = op.target.substring(0, trueLastIndexOf(op.target, '.')); if (pattern.endsWith("property")) { // need to find the right parent. if ("property".equals(pattern)) { @@ -334,22 +330,29 @@ private boolean set(AdminCommandContext context, SetOperation op) { } } - Map> changes = new HashMap>(); - - boolean delProperty = false; - Map attrChanges = new HashMap(); - if (isProperty) { - attrName = "value"; - if ((value == null) || (value.length() == 0)) { - delProperty = true; - } - attrChanges.put(attrName, value); - } List mNodes = new ArrayList(matchingNodes.entrySet()); if (applyOverrideRules) { mNodes = applyOverrideRules(mNodes); } + + + return applyToNodes(context, op, targetName, prefix, pattern, mNodes); + } + + private boolean applyToNodes(AdminCommandContext context, SetOperation op, String targetName, String prefix, String pattern, List mNodes) { + final String value = op.value; + final boolean isProperty = op.isProperty; + final String attrName = op.isProperty ? "value": op.attrName; + final boolean delProperty = isProperty && (value == null || value.isEmpty()); + final String target = op.target; + + + Map> changes = new HashMap>(); + Map attrChanges = new HashMap(); + if (!delProperty) { + attrChanges.put(attrName, value); + } for (Map.Entry node : mNodes) { final Dom targetNode = node.getKey(); From 1ecd722845f46ad4f6d5ef4ed9dceaf1005eca96 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 12 Mar 2019 15:33:15 +0100 Subject: [PATCH 016/108] PAYARA-3466 Fixed: Parameters and Extensions annotation processing, extension to JSON --- .../openapi/api/visitor/ApiVisitor.java | 6 + .../openapi/impl/model/ComponentsImpl.java | 36 ++++-- .../openapi/impl/model/ExtensibleImpl.java | 14 +-- .../openapi/impl/model/ExtensibleTreeMap.java | 11 +- .../openapi/impl/model/OperationImpl.java | 8 +- .../openapi/impl/model/PathItemImpl.java | 8 +- .../openapi/impl/model/PathsImpl.java | 4 +- .../impl/model/callbacks/CallbackImpl.java | 4 +- .../impl/model/headers/HeaderImpl.java | 4 +- .../openapi/impl/model/links/LinkImpl.java | 4 +- .../openapi/impl/model/media/ContentImpl.java | 4 +- .../impl/model/media/DiscriminatorImpl.java | 4 +- .../impl/model/media/EncodingImpl.java | 4 +- .../impl/model/media/MediaTypeImpl.java | 8 +- .../openapi/impl/model/media/SchemaImpl.java | 12 +- .../impl/model/parameters/ParameterImpl.java | 4 +- .../impl/model/responses/APIResponseImpl.java | 8 +- .../model/responses/APIResponsesImpl.java | 6 +- .../impl/model/security/ScopesImpl.java | 2 +- .../security/SecurityRequirementImpl.java | 4 +- .../impl/model/servers/ServerImpl.java | 3 - .../model/servers/ServerVariableImpl.java | 2 +- .../model/servers/ServerVariablesImpl.java | 4 +- .../openapi/impl/model/util/ModelUtils.java | 6 - .../impl/processor/ApplicationProcessor.java | 114 ++++++++++++------ .../openapi/impl/visitor/OpenApiWalker.java | 4 + 26 files changed, 195 insertions(+), 93 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiVisitor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiVisitor.java index 9b68002576e..f98e749eaf7 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiVisitor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiVisitor.java @@ -64,8 +64,10 @@ import org.eclipse.microprofile.openapi.annotations.callbacks.Callback; import org.eclipse.microprofile.openapi.annotations.callbacks.Callbacks; import org.eclipse.microprofile.openapi.annotations.extensions.Extension; +import org.eclipse.microprofile.openapi.annotations.extensions.Extensions; import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; +import org.eclipse.microprofile.openapi.annotations.parameters.Parameters; import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; @@ -126,6 +128,8 @@ interface VisitorFunction { void visitExtension(Extension extension, AnnotatedElement element, ApiContext context); + void visitExtensions(Extensions extensions, AnnotatedElement element, ApiContext context); + void visitOperation(Operation operation, AnnotatedElement element, ApiContext context); void visitCallback(Callback callback, AnnotatedElement element, ApiContext context); @@ -140,6 +144,8 @@ interface VisitorFunction { void visitParameter(Parameter parameter, AnnotatedElement element, ApiContext context); + void visitParameters(Parameters parameters, AnnotatedElement element, ApiContext context); + void visitExternalDocumentation(ExternalDocumentation externalDocs, AnnotatedElement element, ApiContext context); void visitServer(Server server, AnnotatedElement element, ApiContext context); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ComponentsImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ComponentsImpl.java index 51613fdd642..ec507ba02ce 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ComponentsImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ComponentsImpl.java @@ -88,7 +88,9 @@ public void setSchemas(Map schemas) { @Override public Components addSchema(String key, Schema schema) { - schemas.put(key, schema); + if (schema != null) { + schemas.put(key, schema); + } return this; } @@ -109,7 +111,9 @@ public void setResponses(Map responses) { @Override public Components addResponse(String key, APIResponse response) { - responses.put(key, response); + if (response != null) { + responses.put(key, response); + } return this; } @@ -130,7 +134,9 @@ public void setParameters(Map parameters) { @Override public Components addParameter(String key, Parameter parameter) { - parameters.put(key, parameter); + if (parameter != null) { + parameters.put(key, parameter); + } return this; } @@ -151,7 +157,9 @@ public void setExamples(Map examples) { @Override public Components addExample(String key, Example example) { - examples.put(key, example); + if (example != null) { + examples.put(key, example); + } return this; } @@ -172,7 +180,9 @@ public void setRequestBodies(Map requestBodies) { @Override public Components addRequestBody(String key, RequestBody requestBody) { - requestBodies.put(key, requestBody); + if (requestBody != null) { + requestBodies.put(key, requestBody); + } return this; } @@ -193,7 +203,9 @@ public void setHeaders(Map headers) { @Override public Components addHeader(String key, Header header) { - headers.put(key, header); + if (header != null) { + headers.put(key, header); + } return this; } @@ -214,7 +226,9 @@ public void setSecuritySchemes(Map securitySchemes) { @Override public Components addSecurityScheme(String key, SecurityScheme securityScheme) { - securitySchemes.put(key, securityScheme); + if (securityScheme != null) { + securitySchemes.put(key, securityScheme); + } return this; } @@ -235,7 +249,9 @@ public void setLinks(Map links) { @Override public Components addLink(String key, Link link) { - links.put(key, link); + if (link != null) { + links.put(key, link); + } return this; } @@ -256,7 +272,9 @@ public void setCallbacks(Map callbacks) { @Override public Components addCallback(String key, Callback callback) { - callbacks.put(key, callback); + if (callback != null) { + callbacks.put(key, callback); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index 9925f306cf9..1a232aef78a 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -42,24 +42,20 @@ import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.isAnnotationNull; import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.mergeProperty; -import java.io.IOException; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -import javax.json.Json; - import org.eclipse.microprofile.openapi.annotations.extensions.Extension; import org.eclipse.microprofile.openapi.models.Extensible; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.databind.ObjectMapper; public abstract class ExtensibleImpl> implements Extensible { - protected Map extensions = new HashMap<>(); + protected Map extensions = new LinkedHashMap<>(); + @JsonAnyGetter @Override public Map getExtensions() { return extensions; @@ -68,7 +64,9 @@ public Map getExtensions() { @SuppressWarnings("unchecked") @Override public T addExtension(String name, Object value) { - extensions.put(name, value); + if (value != null) { + extensions.put(name, value); + } return (T) this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java index fecd5fd6445..67c8f1318c4 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java @@ -1,15 +1,17 @@ package fish.payara.microprofile.openapi.impl.model; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.TreeMap; import org.eclipse.microprofile.openapi.models.Extensible; +import com.fasterxml.jackson.annotation.JsonAnyGetter; + public abstract class ExtensibleTreeMap> extends TreeMap implements Extensible { - protected Map extensions = new HashMap<>(); + protected Map extensions = new LinkedHashMap<>(); protected ExtensibleTreeMap() { super(); @@ -19,6 +21,7 @@ protected ExtensibleTreeMap(Map items) { super(items); } + @JsonAnyGetter @Override public final Map getExtensions() { return extensions; @@ -32,7 +35,9 @@ public final void setExtensions(Map extensions) { @SuppressWarnings("unchecked") @Override public final T addExtension(String name, Object value) { - this.extensions.put(name, value); + if (value != null) { + this.extensions.put(name, value); + } return (T) this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OperationImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OperationImpl.java index 10d1940ac2c..82d44469dfa 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OperationImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/OperationImpl.java @@ -152,7 +152,9 @@ public void setParameters(List parameters) { @Override public Operation addParameter(Parameter parameter) { - parameters.add(parameter); + if (parameter != null) { + parameters.add(parameter); + } return this; } @@ -193,7 +195,9 @@ public void setCallbacks(Map callbacks) { @Override public Operation addCallback(String key, Callback callback) { - this.callbacks.put(key, callback); + if (callback != null) { + this.callbacks.put(key, callback); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java index 41cf49d074e..48dcdc3e19d 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java @@ -256,7 +256,9 @@ public void setServers(List servers) { @Override public PathItem addServer(Server server) { - servers.add(server); + if (server != null) { + servers.add(server); + } return this; } @@ -277,7 +279,9 @@ public void setParameters(List parameters) { @Override public PathItem addParameter(Parameter parameter) { - parameters.add(parameter); + if (parameter != null) { + parameters.add(parameter); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java index 0fb24e1bb78..25b9610d0b3 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathsImpl.java @@ -60,7 +60,9 @@ public PathsImpl(Map items) { @Override public Paths addPathItem(String name, PathItem item) { - put(name, item); + if (item != null) { + put(name, item); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java index d115314e180..dad382c3898 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java @@ -73,7 +73,9 @@ public CallbackImpl(Map items) { @Override public Callback addPathItem(String name, PathItem item) { - this.put(name, item); + if (item != null) { + this.put(name, item); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java index 61aff64a342..994291f1e22 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java @@ -164,7 +164,9 @@ public void setExamples(Map examples) { @Override public Header addExample(String key, Example examplesItem) { - this.examples.put(key, examplesItem); + if (examplesItem != null) { + this.examples.put(key, examplesItem); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java index 027d385304d..45dde646c0a 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java @@ -115,7 +115,9 @@ public void setParameters(Map parameters) { @Override public Link addParameter(String name, Object parameter) { - this.parameters.put(name, parameter); + if (parameter != null) { + this.parameters.put(name, parameter); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java index 7e2540e1aae..5b3101afe0c 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/ContentImpl.java @@ -66,7 +66,9 @@ public ContentImpl(Map items) { @Override public Content addMediaType(String name, MediaType item) { - this.put(name, item); + if (item != null) { + this.put(name, item); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java index 7d7754bf973..614a0989d3b 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java @@ -71,7 +71,9 @@ public void setMapping(Map mapping) { @Override public Discriminator addMapping(String name, String value) { - mapping.put(name, value); + if (value != null) { + mapping.put(name, value); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java index 94d1b82abf6..4a146052f91 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java @@ -82,7 +82,9 @@ public void setHeaders(Map headers) { @Override public Encoding addHeader(String key, Header header) { - headers.put(key, header); + if (header != null) { + headers.put(key, header); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java index febfa6ed3d5..2a980c9b8d5 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java @@ -78,7 +78,9 @@ public void setExamples(Map examples) { @Override public MediaType addExample(String key, Example example) { - this.examples.put(key, example); + if (example != null) { + this.examples.put(key, example); + } return this; } @@ -109,7 +111,9 @@ public void setEncoding(Map encoding) { @Override public MediaType addEncoding(String key, Encoding encodingItem) { - this.encoding.put(key, encodingItem); + if (encodingItem != null) { + this.encoding.put(key, encodingItem); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java index c13a71a8267..9f2f20aba81 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java @@ -148,7 +148,9 @@ public void setEnumeration(List enumeration) { @Override public Schema addEnumeration(Object enumerationItem) { - this.enumeration.add(enumerationItem); + if (enumerationItem != null) { + this.enumeration.add(enumerationItem); + } return this; } @@ -341,7 +343,9 @@ public void setProperties(Map properties) { @Override public Schema addProperty(String key, Schema propertiesItem) { - this.properties.put(key, propertiesItem); + if (propertiesItem != null) { + this.properties.put(key, propertiesItem); + } return this; } @@ -362,12 +366,12 @@ public void setAdditionalProperties(Schema additionalProperties) { @Override public Schema getAdditionalPropertiesSchema() { - return (Schema) additionalProperties; + return additionalProperties instanceof Schema ? (Schema) additionalProperties : null; } @Override public Boolean getAdditionalPropertiesBoolean() { - return (Boolean) additionalProperties; + return additionalProperties instanceof Boolean ? (Boolean)additionalProperties : null; } @Override diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java index 070d44b218a..7b36cfadbdb 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java @@ -190,7 +190,9 @@ public void setExamples(Map examples) { @Override public Parameter addExample(String key, Example example) { - this.examples.put(key, example); + if (example != null) { + this.examples.put(key, example); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java index 498247f378e..0ede06cf529 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java @@ -87,7 +87,9 @@ public void setHeaders(Map headers) { @Override public APIResponse addHeader(String name, Header header) { - headers.put(name, header); + if (header != null) { + headers.put(name, header); + } return this; } @@ -118,7 +120,9 @@ public void setLinks(Map links) { @Override public APIResponse addLink(String name, Link link) { - links.put(name, link); + if (link != null) { + links.put(name, link); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java index 0a30fb4082f..99fd4de5066 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java @@ -67,7 +67,9 @@ public APIResponsesImpl(Map responses) { @Override public APIResponses addAPIResponse(String name, APIResponse apiResponse) { - put(name, apiResponse); + if (apiResponse != null) { + put(name, apiResponse); + } return this; } @@ -94,7 +96,7 @@ public APIResponse getDefaultValue() { @Override public void setDefaultValue(APIResponse defaultValue) { - addAPIResponse(DEFAULT, defaultValue); + put(DEFAULT, defaultValue); // this is not the same as addAPIResponse as null is set but not added } public static void merge(org.eclipse.microprofile.openapi.annotations.responses.APIResponse from, APIResponses to, diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java index d0ff158c036..5718f9903eb 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/ScopesImpl.java @@ -59,7 +59,7 @@ public ScopesImpl(Map scopes) { @Override public Scopes addScope(String name, String item) { - this.put(name, item); + this.put(name, item); // this DOES accept null! return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecurityRequirementImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecurityRequirementImpl.java index 381e2b1789a..6afff0c8785 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecurityRequirementImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecurityRequirementImpl.java @@ -63,13 +63,13 @@ public SecurityRequirementImpl(Map> ite @Override public SecurityRequirement addScheme(String name, String item) { - this.put(name, Arrays.asList(item)); + this.put(name, item == null ? new ArrayList<>() : Arrays.asList(item)); return this; } @Override public SecurityRequirement addScheme(String name, List item) { - this.put(name, item); + this.put(name, item == null ? new ArrayList<>() : item); return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java index 14bdf340c38..566764f8c8a 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java @@ -44,9 +44,6 @@ import java.util.Map; -import javax.json.bind.annotation.JsonbProperty; -import javax.xml.bind.annotation.XmlTransient; - import org.eclipse.microprofile.openapi.models.servers.Server; import org.eclipse.microprofile.openapi.models.servers.ServerVariable; import org.eclipse.microprofile.openapi.models.servers.ServerVariables; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java index b180b25f34f..20f4c61c702 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java @@ -85,7 +85,7 @@ public void setEnumeration(List enumeration) { @Override public ServerVariable addEnumeration(String enumeration) { - if (!this.enumeration.contains(enumeration)) { + if (enumeration != null && !this.enumeration.contains(enumeration)) { this.enumeration.add(enumeration); } return this; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java index 6e2b9d31a34..fd03abb645a 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariablesImpl.java @@ -64,7 +64,9 @@ public ServerVariablesImpl(Map variables) { @Override public ServerVariables addServerVariable(String name, ServerVariable item) { - this.put(name, item); + if (item != null) { + this.put(name, item); + } return this; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java index a0202bc73df..1f58455efc8 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java @@ -313,12 +313,6 @@ public static SchemaType getParentSchemaType(SchemaType type1, SchemaType type2) if (type2 == null) { return type1; } - if (type1 == SchemaType.OBJECT || type2 == SchemaType.OBJECT) { - return SchemaType.OBJECT; - } - if (type1 == SchemaType.STRING || type2 == SchemaType.STRING) { - return SchemaType.STRING; - } if (type1 != type2) { return SchemaType.STRING; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java index 71234583e9f..9f908c1433e 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java @@ -81,8 +81,10 @@ import org.eclipse.microprofile.openapi.annotations.callbacks.Callbacks; import org.eclipse.microprofile.openapi.annotations.enums.ParameterIn; import org.eclipse.microprofile.openapi.annotations.extensions.Extension; +import org.eclipse.microprofile.openapi.annotations.extensions.Extensions; import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; +import org.eclipse.microprofile.openapi.annotations.parameters.Parameters; import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; @@ -106,6 +108,7 @@ import fish.payara.microprofile.openapi.api.visitor.ApiVisitor; import fish.payara.microprofile.openapi.api.visitor.ApiWalker; import fish.payara.microprofile.openapi.impl.config.OpenApiConfiguration; +import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; import fish.payara.microprofile.openapi.impl.model.ExternalDocumentationImpl; import fish.payara.microprofile.openapi.impl.model.OpenAPIImpl; import fish.payara.microprofile.openapi.impl.model.OperationImpl; @@ -633,16 +636,26 @@ private void visitSchemaParameter(Schema schema, java.lang.reflect.Parameter par @Override public void visitExtension(Extension extension, AnnotatedElement element, ApiContext context) { - if (extension.name() != null && !extension.name().isEmpty() && extension.value() != null - && !extension.value().isEmpty()) { + String value = extension.value(); + String name = extension.name(); + if (name != null && !name.isEmpty() && value != null + && !value.isEmpty()) { + Object parsedValue = ExtensibleImpl.convertExtensionValue(value, extension.parseValue()); if (element instanceof Method) { - context.getWorkingOperation().addExtension(extension.name(), extension.value()); + context.getWorkingOperation().addExtension(name, parsedValue); } else { - context.getApi().addExtension(extension.name(), extension.value()); + context.getApi().addExtension(name, parsedValue); } } } + @Override + public void visitExtensions(Extensions extensions, AnnotatedElement element, ApiContext context) { + for (Extension extension : extensions.value()) { + visitExtension(extension, element, context); + } + } + @Override public void visitOperation(Operation operation, AnnotatedElement element, ApiContext context) { OperationImpl.merge(operation, context.getWorkingOperation(), true); @@ -712,47 +725,23 @@ public void visitAPIResponses(APIResponses apiResponses, AnnotatedElement elemen } } + @Override + public void visitParameters(Parameters parameters, AnnotatedElement element, ApiContext context) { + for (Parameter parameter : parameters.value()) { + visitParameter(parameter, element, context); + } + } + @Override public void visitParameter(Parameter parameter, AnnotatedElement element, ApiContext context) { org.eclipse.microprofile.openapi.models.parameters.Parameter matchedParam = null; if (element instanceof java.lang.reflect.Parameter) { - // Find the matching parameter, and match it - for (org.eclipse.microprofile.openapi.models.parameters.Parameter param : context.getWorkingOperation() - .getParameters()) { - if (param.getName() != null - && param.getName().equals(ModelUtils.getParameterName((java.lang.reflect.Parameter) element))) { - matchedParam = param; - } - } + matchedParam = findOperationParameterFor((java.lang.reflect.Parameter) element, context); } if (element instanceof Method) { - // If the parameter reference is valid - if (parameter.name() != null && !parameter.name().isEmpty()) { - // Get all parameters with the same name - List matchingMethodParameters = Arrays - .asList(Method.class.cast(element).getParameters()).stream() - .filter(x -> ModelUtils.getParameterName(x).equals(parameter.name())) - .collect(Collectors.toList()); - // If there is more than one match, filter it further - if (matchingMethodParameters.size() > 1 && parameter.in() != null - && parameter.in() != ParameterIn.DEFAULT) { - // Remove all parameters of the wrong input type - matchingMethodParameters - .removeIf(x -> ModelUtils.getParameterType(x) != In.valueOf(parameter.in().name())); - } - // If there's only one matching parameter, handle it immediately - String matchingMethodParamName = ModelUtils.getParameterName(matchingMethodParameters.get(0)); - // Find the matching operation parameter - for (org.eclipse.microprofile.openapi.models.parameters.Parameter operationParam : context - .getWorkingOperation().getParameters()) { - if (operationParam.getName().equals(matchingMethodParamName)) { - matchedParam = operationParam; - } - } - } + matchedParam = findOperationParameterFor(parameter, (Method) element, context); } - if (matchedParam != null) { ParameterImpl.merge(parameter, matchedParam, true, context.getApi().getComponents().getSchemas()); @@ -773,6 +762,57 @@ public void visitParameter(Parameter parameter, AnnotatedElement element, ApiCon } } + private static org.eclipse.microprofile.openapi.models.parameters.Parameter findOperationParameterFor(Parameter parameter, + Method annotated, ApiContext context) { + String name = parameter.name(); + // If the parameter reference is valid + if (name != null && !name.isEmpty()) { + // Get all parameters with the same name + List matchingMethodParameters = Arrays + .asList(annotated.getParameters()).stream() + .filter(x -> name.equals(ModelUtils.getParameterName(x))) + .collect(Collectors.toList()); + // If there is more than one match, filter it further + ParameterIn in = parameter.in(); + if (matchingMethodParameters.size() > 1 && in != null && in != ParameterIn.DEFAULT) { + // Remove all parameters of the wrong input type + matchingMethodParameters + .removeIf(x -> ModelUtils.getParameterType(x) != In.valueOf(in.name())); + } + if (matchingMethodParameters.isEmpty()) { + return null; + } + // If there's only one matching parameter, handle it immediately + String matchingMethodParamName = ModelUtils.getParameterName(matchingMethodParameters.get(0)); + // Find the matching operation parameter + for (org.eclipse.microprofile.openapi.models.parameters.Parameter operationParam : context + .getWorkingOperation().getParameters()) { + if (operationParam.getName().equals(matchingMethodParamName)) { + return operationParam; + } + } + } + return null; + } + + /** + * Find the matching parameter, and match it + */ + private static org.eclipse.microprofile.openapi.models.parameters.Parameter findOperationParameterFor( + java.lang.reflect.Parameter annotated, ApiContext context) { + String actualName = ModelUtils.getParameterName(annotated); + if (actualName == null) { + return null; + } + for (org.eclipse.microprofile.openapi.models.parameters.Parameter param : context.getWorkingOperation() + .getParameters()) { + if (actualName.equals(param.getName())) { + return param; + } + } + return null; + } + @Override public void visitExternalDocumentation(ExternalDocumentation externalDocs, AnnotatedElement element, ApiContext context) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java index 79502e7a6e0..73be00453c1 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java @@ -74,8 +74,10 @@ import org.eclipse.microprofile.openapi.annotations.callbacks.Callback; import org.eclipse.microprofile.openapi.annotations.callbacks.Callbacks; import org.eclipse.microprofile.openapi.annotations.extensions.Extension; +import org.eclipse.microprofile.openapi.annotations.extensions.Extensions; import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; +import org.eclipse.microprofile.openapi.annotations.parameters.Parameters; import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; @@ -153,11 +155,13 @@ public void accept(ApiVisitor visitor) { // All other OpenAPI annotations processAnnotations(Schema.class, visitor::visitSchema, true); processAnnotations(Server.class, visitor::visitServer, Servers.class, visitor::visitServers, true); + processAnnotations(Extensions.class, visitor::visitExtensions, true); processAnnotations(Extension.class, visitor::visitExtension, true); processAnnotations(Operation.class, visitor::visitOperation); processAnnotations(Callback.class, visitor::visitCallback, Callbacks.class, visitor::visitCallbacks); processAnnotations(APIResponse.class, visitor::visitAPIResponse, APIResponses.class, visitor::visitAPIResponses, true); + processAnnotations(Parameters.class, visitor::visitParameters, true); processAnnotations(Parameter.class, visitor::visitParameter, true); processAnnotations(ExternalDocumentation.class, visitor::visitExternalDocumentation, true); processAnnotations(Tag.class, visitor::visitTag, Tags.class, visitor::visitTags, true); From 866043e0a26c01c44c1e664a7f95535670eb802e Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Tue, 12 Mar 2019 15:52:55 +0100 Subject: [PATCH 017/108] PAYARA-3444: Warn when shared config is changed when referring to server node --- .../sun/enterprise/v3/admin/SetCommand.java | 56 +++++++++++++------ 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java index 5aba702cc36..b9653c35eae 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2017] [Payara Foundation and/or its affiliates] +// Portions Copyright [2017-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.v3.admin; import com.sun.enterprise.admin.util.ClusterOperationUtil; @@ -49,20 +49,21 @@ import org.glassfish.api.ActionReport; import org.glassfish.api.I18n; import org.glassfish.api.Param; +import org.glassfish.api.admin.AccessRequired.AccessCheck; import org.glassfish.api.admin.AdminCommand; import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.AdminCommandSecurity; import org.glassfish.api.admin.ExecuteOn; import org.glassfish.api.admin.FailurePolicy; import org.glassfish.api.admin.ParameterMap; import org.glassfish.api.admin.RuntimeType; import org.glassfish.api.admin.config.LegacyConfigurationUpgrade; -import org.glassfish.internal.api.Target; - -import org.jvnet.hk2.annotations.Optional; -import org.jvnet.hk2.annotations.Service; import org.glassfish.hk2.api.PerLookup; import org.glassfish.hk2.api.PostConstruct; import org.glassfish.hk2.api.ServiceLocator; +import org.glassfish.internal.api.Target; +import org.jvnet.hk2.annotations.Optional; +import org.jvnet.hk2.annotations.Service; import org.jvnet.hk2.config.ConfigBean; import org.jvnet.hk2.config.ConfigBeanProxy; import org.jvnet.hk2.config.ConfigModel; @@ -88,9 +89,7 @@ import java.util.List; import java.util.Map; import java.util.StringTokenizer; - -import org.glassfish.api.admin.AccessRequired.AccessCheck; -import org.glassfish.api.admin.AdminCommandSecurity; +import java.util.stream.Collectors; /** * User: Jerome Dochez Date: Jul 11, 2008 Time: 4:39:05 AM @@ -274,18 +273,19 @@ private boolean set(AdminCommandContext context, SetOperation op) { // reset the pattern. String prefix; boolean lookAtSubNodes = true; - if (parentNodes[0].relativeName.length() == 0 - || parentNodes[0].relativeName.equals("domain")) { + TreeNode primaryNode = parentNodes[0]; + if (primaryNode.relativeName.length() == 0 + || primaryNode.relativeName.equals("domain")) { // handle the case where the pattern references an attribute of the top-level node prefix = ""; // pattern is already set properly lookAtSubNodes = false; - } else if (!pattern.startsWith(parentNodes[0].relativeName)) { - prefix = pattern.substring(0, pattern.indexOf(parentNodes[0].relativeName)); - pattern = parentNodes[0].relativeName; + } else if (!pattern.startsWith(primaryNode.relativeName)) { + prefix = pattern.substring(0, pattern.indexOf(primaryNode.relativeName)); + pattern = primaryNode.relativeName; } else { prefix = ""; - pattern = parentNodes[0].relativeName; + pattern = primaryNode.relativeName; } String targetName = prefix + pattern; @@ -301,9 +301,12 @@ private boolean set(AdminCommandContext context, SetOperation op) { Map matchingNodes; boolean applyOverrideRules = false; Map dottedNames = new HashMap(); + Map sourceNodes = new HashMap<>(); if (lookAtSubNodes) { for (TreeNode parentNode : parentNodes) { - dottedNames.putAll(getAllDottedNodes(parentNode.node)); + Map allDottedNodes = getAllDottedNodes(parentNode.node); + dottedNames.putAll(allDottedNodes); + allDottedNodes.keySet().forEach(dom -> sourceNodes.put(dom, parentNode)); } matchingNodes = getMatchingNodes(dottedNames, pattern); applyOverrideRules = true; @@ -330,13 +333,34 @@ private boolean set(AdminCommandContext context, SetOperation op) { } } - List mNodes = new ArrayList(matchingNodes.entrySet()); if (applyOverrideRules) { mNodes = applyOverrideRules(mNodes); } + if (primaryNode.node.getProxyType().equals(Server.class)) { + // if the user thinks server configuration is being changed, warn him if matching nodes are different + + // from matching nodes, find the roots that are in parentNodes + String targets = mNodes.stream() + .map(Map.Entry::getKey) + .map(sourceNodes::get) + // should definitely be in the map, but just to be sure + .filter(n -> n != null && n != primaryNode) + // if not the primary node, make description like "Config shared-config, ..." + .map(treeNode -> treeNode.node) + .map(treeNode -> treeNode.getProxyType().getSimpleName() +" "+ treeNode.getKey()) + .collect(Collectors.joining(", ")); + + if (!targets.isEmpty()) { + warning(context, localStrings.getLocalString("admin.set.sharedconfig", + "Warning: command appears to address server {0}, but addresses following shared configuration(s): {1}", + primaryNode.name, targets)); + } + } + + return applyToNodes(context, op, targetName, prefix, pattern, mNodes); } From 2ba0ee26ef166ca40520a504fa4e3769d737ccfe Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Tue, 12 Mar 2019 16:44:54 +0100 Subject: [PATCH 018/108] PAYARA-3444: Check that referenced config is actually shared before putting out a warning --- .../sun/enterprise/v3/admin/SetCommand.java | 53 ++++++++++++------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java index b9653c35eae..58e1a46410b 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java @@ -43,6 +43,7 @@ import com.sun.enterprise.admin.util.ClusterOperationUtil; import com.sun.enterprise.config.modularity.ConfigModularityUtils; import com.sun.enterprise.config.modularity.GetSetModularityHelper; +import com.sun.enterprise.config.serverbeans.Config; import com.sun.enterprise.config.serverbeans.Domain; import com.sun.enterprise.config.serverbeans.Server; import com.sun.enterprise.util.LocalStringManagerImpl; @@ -88,6 +89,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.StringTokenizer; import java.util.stream.Collectors; @@ -340,30 +342,45 @@ private boolean set(AdminCommandContext context, SetOperation op) { if (primaryNode.node.getProxyType().equals(Server.class)) { - // if the user thinks server configuration is being changed, warn him if matching nodes are different - - // from matching nodes, find the roots that are in parentNodes - String targets = mNodes.stream() - .map(Map.Entry::getKey) - .map(sourceNodes::get) - // should definitely be in the map, but just to be sure - .filter(n -> n != null && n != primaryNode) - // if not the primary node, make description like "Config shared-config, ..." - .map(treeNode -> treeNode.node) - .map(treeNode -> treeNode.getProxyType().getSimpleName() +" "+ treeNode.getKey()) - .collect(Collectors.joining(", ")); - - if (!targets.isEmpty()) { - warning(context, localStrings.getLocalString("admin.set.sharedconfig", - "Warning: command appears to address server {0}, but addresses following shared configuration(s): {1}", - primaryNode.name, targets)); - } + checkSharedConfigChange(context, primaryNode, sourceNodes, mNodes); } return applyToNodes(context, op, targetName, prefix, pattern, mNodes); } + private void checkSharedConfigChange(AdminCommandContext context, TreeNode primaryNode, Map sourceNodes, List mNodes) { + // if the user thinks server configuration is being changed, warn him if matching nodes are different + Set sharedConfigs = findSharedConfigs(); + // from matching nodes, find the roots that are in parentNodes + String targetedSharedConfigs = mNodes.stream() + .map(Map.Entry::getKey) + .map(sourceNodes::get) + // should definitely be in the map, but just to be sure + .filter(n -> n != null) + .map(n -> n.node) + .filter(sharedConfigs::contains) + // if not the primary node, make description like "Config shared-config, ..." + .map(Dom::getKey) + .collect(Collectors.joining(", ")); + + if (!targetedSharedConfigs.isEmpty()) { + warning(context, localStrings.getLocalString("admin.set.sharedconfig", + "Warning: command appears to address server {0}, but addresses following shared configuration(s): {1}", + primaryNode.name, targetedSharedConfigs)); + } + } + + private Set findSharedConfigs() { + List servers = domain.getServers().getServer(); + List configs = domain.getConfigs().getConfig(); + return configs.stream().filter(config -> countConfigUses(servers, config) > 1).map(Dom::unwrap).collect(Collectors.toSet()); + } + + private long countConfigUses(List servers, Config config) { + return servers.stream().map(Server::getReference).filter(config.getName()::equals).count(); + } + private boolean applyToNodes(AdminCommandContext context, SetOperation op, String targetName, String prefix, String pattern, List mNodes) { final String value = op.value; final boolean isProperty = op.isProperty; From d85abf821297f5f74f8fbb9f6bd378215d314bfa Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 12 Mar 2019 16:49:52 +0100 Subject: [PATCH 019/108] PAYARA-3466 fixed JSON serialisation issues --- .../openapi/impl/model/ExtensibleImpl.java | 32 +++++++++++++++++++ .../openapi/impl/model/PathItemImpl.java | 3 ++ 2 files changed, 35 insertions(+) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index 1a232aef78a..97556cb34ba 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -42,6 +42,8 @@ import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.isAnnotationNull; import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.mergeProperty; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.LinkedHashMap; import java.util.Map; @@ -127,4 +129,34 @@ public static Object convertExtensionValue(String value, boolean parseValue) { return value; } + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + toString(str, "\t"); + return str.toString(); + } + + void toString(StringBuilder str, String indent) { + str.append(getClass().getSimpleName()); + Class type = getClass(); + while (type != Object.class) { + for (Field field : type.getDeclaredFields()) { + if (!Modifier.isStatic(field.getModifiers()) && !field.isSynthetic()) { + str.append("\n").append(indent).append(field.getName()).append(": "); + try { + field.setAccessible(true); + Object value = field.get(this); + if (value instanceof ExtensibleImpl) { + ((ExtensibleImpl)value).toString(str, indent + "\t"); + } else { + str.append(value); + } + } catch (IllegalArgumentException | IllegalAccessException e) { + str.append(""); + } + } + } + type = type.getSuperclass(); + } + } } \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java index 48dcdc3e19d..a3fa982fe03 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java @@ -50,6 +50,8 @@ import org.eclipse.microprofile.openapi.models.parameters.Parameter; import org.eclipse.microprofile.openapi.models.servers.Server; +import com.fasterxml.jackson.annotation.JsonIgnore; + public class PathItemImpl extends ExtensibleImpl implements PathItem { protected String ref; @@ -176,6 +178,7 @@ public void setTRACE(Operation trace) { this.trace = trace; } + @JsonIgnore @Override public Map getOperations() { return readOperationsMap(); From 5a44ff2526a767b48d68b340a547050b8bef81fe Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Wed, 13 Mar 2019 11:31:31 +0100 Subject: [PATCH 020/108] PAYARA-3466 fixed extension JSON parsing --- .../openapi/impl/model/ExtensibleImpl.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index 97556cb34ba..e655d759b7b 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -46,15 +46,19 @@ import java.lang.reflect.Modifier; import java.util.LinkedHashMap; import java.util.Map; +import java.util.logging.Logger; import org.eclipse.microprofile.openapi.annotations.extensions.Extension; import org.eclipse.microprofile.openapi.models.Extensible; import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; public abstract class ExtensibleImpl> implements Extensible { + private static final Logger LOGGER = Logger.getLogger(ExtensibleImpl.class.getName()); + protected Map extensions = new LinkedHashMap<>(); @JsonAnyGetter @@ -101,21 +105,19 @@ public static Object convertExtensionValue(String value, boolean parseValue) { return null; } if (parseValue) { - if (value.startsWith("{") || value.startsWith("[")) { // JSON object + array - try { - return new ObjectMapper().readTree(value); - } catch (Exception e) { - return value; + try { + JsonNode node = new ObjectMapper().readTree(value); + if (node.isBoolean()) { + return node.booleanValue(); } + if (node.isNumber()) { + return node.numberValue(); + } + return node; + } catch (Exception e) { + LOGGER.warning("Failed to parse extension value: " + value); + return value; } - if ("true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value)) { - return Boolean.valueOf(value); - } - // must be number - if (value.indexOf('.') >= 0) { - return Double.valueOf(value); - } - return Long.valueOf(value); } // Could be an array if (value.contains(",")) { From 9cbe6470db2d41af54030efd2af45c6ebb28a1b2 Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Wed, 13 Mar 2019 11:12:18 +0000 Subject: [PATCH 021/108] Fixed contextroot issue for console and deployment dir deployments --- .../micro/boot/PayaraMicroLauncher.java | 5 + .../payara/micro/boot/loader/Launcher.java | 214 +++++++++--------- .../payara/micro/impl/PayaraMicroImpl.java | 160 +++++++------ 3 files changed, 201 insertions(+), 178 deletions(-) diff --git a/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/PayaraMicroLauncher.java b/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/PayaraMicroLauncher.java index a9d3793decb..1a797f9cbe0 100644 --- a/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/PayaraMicroLauncher.java +++ b/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/PayaraMicroLauncher.java @@ -69,6 +69,11 @@ public class PayaraMicroLauncher extends ExecutableArchiveLauncher { * @throws Exception */ public static void main(String args[]) throws Exception { + System.out.println("########################################################################################"); + for(String arg : args) { + System.out.println(arg); + } + System.out.println("########################################################################################"); create("main", args); } diff --git a/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/loader/Launcher.java b/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/loader/Launcher.java index acffbd8eeff..dae4a56db23 100644 --- a/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/loader/Launcher.java +++ b/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/loader/Launcher.java @@ -14,7 +14,6 @@ * limitations under the License. */ // Modified 2017 Payara Foundation - package fish.payara.micro.boot.loader; import java.io.File; @@ -29,124 +28,133 @@ import fish.payara.micro.boot.loader.archive.JarFileArchive; /** - * Base class for launchers that can start an application with a fully configured - * classpath backed by one or more {@link Archive}s. + * Base class for launchers that can start an application with a fully + * configured classpath backed by one or more {@link Archive}s. * * @author Phillip Webb * @author Dave Syer */ public abstract class Launcher { - /** - * Launch the application. This method is the initial entry point that should be - * called by a subclass {@code public static void main(String[] args)} method. - * @param args the incoming arguments - * @throws Exception if the application fails to launch - */ - protected Object launch(String method, String[] args) throws Exception { - boolean explode = true; - String unpackDir = null; - for (int i = 0; i < args.length; i++) { - if ("--nested".equals(args[i].toLowerCase())) { - explode = false; - } else if ("--unpackdir".equals(args[i].toLowerCase()) || "--rootdir".equals(args[i].toLowerCase())) { - if (args.length >= (i+1)) { - unpackDir = args[i+1]; - } + /** + * Launch the application. This method is the initial entry point that + * should be called by a subclass + * {@code public static void main(String[] args)} method. + * + * @param args the incoming arguments + * @throws Exception if the application fails to launch + */ + protected Object launch(String method, String[] args) throws Exception { + boolean explode = true; + String unpackDir = null; + for (int i = 0; i < args.length; i++) { + if ("--nested".equals(args[i].toLowerCase())) { + explode = false; + } else if ("--unpackdir".equals(args[i].toLowerCase()) || "--rootdir".equals(args[i].toLowerCase())) { + if (args.length >= (i + 1)) { + unpackDir = args[i + 1]; } } - - ClassLoader classLoader; - if (!explode) { - classLoader = createClassLoader(getClassPathArchives()); - fish.payara.micro.boot.loader.jar.JarFile.registerUrlProtocolHandler(); + } + + ClassLoader classLoader; + if (!explode) { + classLoader = createClassLoader(getClassPathArchives()); + fish.payara.micro.boot.loader.jar.JarFile.registerUrlProtocolHandler(); + } else { + if (unpackDir != null) { + classLoader = new ExplodedURLClassloader(new File(unpackDir)); } else { - if (unpackDir != null) { - classLoader = new ExplodedURLClassloader(new File(unpackDir)); - } else { - classLoader = new ExplodedURLClassloader(); - } + classLoader = new ExplodedURLClassloader(); } - return launch(method, args, getMainClass(), classLoader); - } + } + return launch(method, args, getMainClass(), classLoader); + } - /** - * Create a classloader for the specified archives. - * @param archives the archives - * @return the classloader - * @throws Exception if the classloader cannot be created - */ - protected ClassLoader createClassLoader(List archives) throws Exception { - List urls = new ArrayList(archives.size()); - for (Archive archive : archives) { - urls.add(archive.getUrl()); - } - return createClassLoader(urls.toArray(new URL[urls.size()])); - } + /** + * Create a classloader for the specified archives. + * + * @param archives the archives + * @return the classloader + * @throws Exception if the classloader cannot be created + */ + protected ClassLoader createClassLoader(List archives) throws Exception { + List urls = new ArrayList(archives.size()); + for (Archive archive : archives) { + urls.add(archive.getUrl()); + } + return createClassLoader(urls.toArray(new URL[urls.size()])); + } - /** - * Create a classloader for the specified URLs. - * @param urls the URLs - * @return the classloader - * @throws Exception if the classloader cannot be created - */ - protected ClassLoader createClassLoader(URL[] urls) throws Exception { - return new LaunchedURLClassLoader(urls, getClass().getClassLoader()); - } + /** + * Create a classloader for the specified URLs. + * + * @param urls the URLs + * @return the classloader + * @throws Exception if the classloader cannot be created + */ + protected ClassLoader createClassLoader(URL[] urls) throws Exception { + return new LaunchedURLClassLoader(urls, getClass().getClassLoader()); + } - /** - * Launch the application given the archive file and a fully configured classloader. - * @param args the incoming arguments - * @param mainClass the main class to run - * @param classLoader the classloader - * @throws Exception if the launch fails - */ - protected Object launch(String method, String[] args, String mainClass, ClassLoader classLoader) - throws Exception { - Thread.currentThread().setContextClassLoader(classLoader); - return createMainMethodRunner(mainClass, method, args, classLoader).run(); - } + /** + * Launch the application given the archive file and a fully configured + * classloader. + * + * @param args the incoming arguments + * @param mainClass the main class to run + * @param classLoader the classloader + * @throws Exception if the launch fails + */ + protected Object launch(String method, String[] args, String mainClass, ClassLoader classLoader) + throws Exception { + Thread.currentThread().setContextClassLoader(classLoader); + return createMainMethodRunner(mainClass, method, args, classLoader).run(); + } - /** - * Create the {@code MainMethodRunner} used to launch the application. - * @param mainClass the main class - * @param args the incoming arguments - * @param classLoader the classloader - * @return the main method runner - */ - protected MainMethodRunner createMainMethodRunner(String mainClass, String method, String[] args, - ClassLoader classLoader) { - return new MainMethodRunner(mainClass, args, method); - } + /** + * Create the {@code MainMethodRunner} used to launch the application. + * + * @param mainClass the main class + * @param args the incoming arguments + * @param classLoader the classloader + * @return the main method runner + */ + protected MainMethodRunner createMainMethodRunner(String mainClass, String method, String[] args, + ClassLoader classLoader) { + return new MainMethodRunner(mainClass, args, method); + } - /** - * Returns the main class that should be launched. - * @return the name of the main class - * @throws Exception if the main class cannot be obtained - */ - protected abstract String getMainClass() throws Exception; + /** + * Returns the main class that should be launched. + * + * @return the name of the main class + * @throws Exception if the main class cannot be obtained + */ + protected abstract String getMainClass() throws Exception; - /** - * Returns the archives that will be used to construct the class path. - * @return the class path archives - * @throws Exception if the class path archives cannot be obtained - */ - protected abstract List getClassPathArchives() throws Exception; + /** + * Returns the archives that will be used to construct the class path. + * + * @return the class path archives + * @throws Exception if the class path archives cannot be obtained + */ + protected abstract List getClassPathArchives() throws Exception; - protected final Archive createArchive() throws Exception { - ProtectionDomain protectionDomain = getClass().getProtectionDomain(); - CodeSource codeSource = protectionDomain.getCodeSource(); - URI location = (codeSource == null ? null : codeSource.getLocation().toURI()); - String path = (location == null ? null : location.getSchemeSpecificPart()); - if (path == null) { - throw new IllegalStateException("Unable to determine code source archive"); - } - File root = new File(path); - if (!root.exists()) { - throw new IllegalStateException( - "Unable to determine code source archive from " + root); - } - return new JarFileArchive(root); - } + protected final Archive createArchive() throws Exception { + ProtectionDomain protectionDomain = getClass().getProtectionDomain(); + CodeSource codeSource = protectionDomain.getCodeSource(); + URI location = (codeSource == null ? null : codeSource.getLocation().toURI()); + String path = (location == null ? null : location.getSchemeSpecificPart()); + if (path == null) { + throw new IllegalStateException("Unable to determine code source archive"); + } + File root = new File(path); + if (!root.exists()) { + throw new IllegalStateException( + "Unable to determine code source archive from " + root); + } + return new JarFileArchive(root); + } } diff --git a/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java b/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java index 17bcbb5da18..90869c91d81 100644 --- a/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java +++ b/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java @@ -111,7 +111,7 @@ public class PayaraMicroImpl implements PayaraMicroBoot { private static final String BOOT_PROPS_FILE = "/MICRO-INF/payara-boot.properties"; private static final String USER_PROPS_FILE = "MICRO-INF/deploy/payaramicro.properties"; private static final String CONTEXT_PROPS_FILE = "MICRO-INF/deploy/contexts.properties"; - + private static final Logger LOGGER = Logger.getLogger("PayaraMicro"); private static PayaraMicroImpl instance; @@ -341,7 +341,7 @@ public PayaraMicroImpl setLogPropertiesFile(File fileName) { * Set user defined file directory for the access log * * @param filePath - * @return + * @return */ @Override public PayaraMicroBoot setAccessLogDir(String filePath) { @@ -354,7 +354,7 @@ public PayaraMicroBoot setAccessLogDir(String filePath) { * Set user defined formatting for the access log * * @param format - * @return + * @return */ @Override public PayaraMicroBoot setAccessLogFormat(String format) { @@ -455,7 +455,7 @@ public PayaraMicroImpl setHttpPort(int httpPort) { public File getUberJar() { return uberJar; } - + /** * The configured port for HTTPS requests * @@ -482,7 +482,7 @@ public PayaraMicroImpl setSslPort(int sslPort) { this.sslPort = sslPort; return this; } - + @Override public PayaraMicroImpl setSniEnabled(boolean value) { sniEnabled = value; @@ -491,20 +491,21 @@ public PayaraMicroImpl setSniEnabled(boolean value) { /** * Set the certificate alias in the keystore to use for the server cert + * * @param alias name of the certificate in the keystore - * @return + * @return */ @Override public PayaraMicroImpl setSslCert(String alias) { sslCert = alias; return this; } - + @Override public String getSslCert() { return sslCert; } - + /** * Gets the logical name for this PayaraMicro Server within the server * cluster @@ -1037,7 +1038,6 @@ public PayaraMicroRuntime bootStrap() throws BootstrapException { // Execute post boot commands postBootCommands.executeCommands(gf.getCommandRunner()); - this.runtime = new PayaraMicroRuntimeImpl(gf, gfruntime); // load all applications, but do not start them until Hazelcast gets a chance to initialize @@ -1045,8 +1045,8 @@ public PayaraMicroRuntime bootStrap() throws BootstrapException { } finally { HazelcastCore.setThreadLocalDisabled(false); } - if(!noCluster) { - gf.getCommandRunner().run("set-hazelcast-configuration", "--enabled", "true", "--dynamic", "true", "--target", "server-config", "--hostawarepartitioning", Boolean.toString(hostAware),"--lite", Boolean.toString(liteMember)); + if (!noCluster) { + gf.getCommandRunner().run("set-hazelcast-configuration", "--enabled", "true", "--dynamic", "true", "--target", "server-config", "--hostawarepartitioning", Boolean.toString(hostAware), "--lite", Boolean.toString(liteMember)); } gf.getCommandRunner().run("initialize-all-applications"); @@ -1189,7 +1189,7 @@ private void scanArgs(String[] args) { case addlibs: case addjars: List files = UberJarCreator.parseFileList(value, File.pathSeparator); - if(!files.isEmpty()) { + if (!files.isEmpty()) { if (libraries == null) { libraries = new LinkedList<>(); } @@ -1201,12 +1201,12 @@ private void scanArgs(String[] args) { if (deployments == null) { deployments = new LinkedList<>(); contextRoots = new Properties(); - } + } String fileName = value; String deployContext = null; if (value != null && value.contains(File.pathSeparator)) { - fileName = value.substring(0,value.indexOf(File.pathSeparatorChar)); - deployContext = value.substring(value.indexOf(File.pathSeparatorChar)+1); + fileName = value.substring(0, value.indexOf(File.pathSeparatorChar)); + deployContext = value.substring(value.indexOf(File.pathSeparatorChar) + 1); } File deployment = new File(fileName); deployments.add(deployment); @@ -1245,7 +1245,7 @@ private void scanArgs(String[] args) { GAVs.add(value); break; case additionalrepository: - repositoryURLs.add(value); + repositoryURLs.add(value); break; case outputuberjar: uberJar = new File(value); @@ -1258,7 +1258,7 @@ private void scanArgs(String[] args) { break; case enablerequesttracing: enableRequestTracing = true; - + // Check if a value has actually been given // Split strings from numbers if (value != null) { @@ -1267,11 +1267,11 @@ private void scanArgs(String[] args) { if (requestTracing.length <= 2) { // If the first entry is a number if (requestTracing[0].matches("\\d+")) { - requestTracingThresholdValue = parseArgument(requestTracing[0], + requestTracingThresholdValue = parseArgument(requestTracing[0], "request tracing threshold value", Long::parseLong).longValue(); // If there is a second entry, and it's a String if (requestTracing.length == 2 && requestTracing[1].matches("\\D+")) { - requestTracingThresholdUnit = parseTimeUnit(requestTracing[1], + requestTracingThresholdUnit = parseTimeUnit(requestTracing[1], "request tracing threshold unit").name(); } // If there is a second entry, and it's not a String else if (requestTracing.length == 2 && !requestTracing[1].matches("\\D+")) { @@ -1279,7 +1279,7 @@ else if (requestTracing.length == 2 && !requestTracing[1].matches("\\D+")) { } } // If the first entry is a String else if (requestTracing[0].matches("\\D+")) { - requestTracingThresholdUnit = parseTimeUnit(requestTracing[0], + requestTracingThresholdUnit = parseTimeUnit(requestTracing[0], "request tracing threshold unit").name(); // There shouldn't be a second entry if (requestTracing.length == 2) { @@ -1295,7 +1295,7 @@ else if (requestTracing[0].matches("\\D+")) { requestTracingThresholdUnit = parseTimeUnit(value, "value for --requestTracingThresholdUnit").name(); break; case requesttracingthresholdvalue: - requestTracingThresholdValue = parseArgument(value, "value for --requestTracingThresholdValue", + requestTracingThresholdValue = parseArgument(value, "value for --requestTracingThresholdValue", Long::parseLong).longValue(); break; case enablerequesttracingadaptivesampling: @@ -1370,6 +1370,7 @@ else if (requestTracing[0].matches("\\D+")) { initialJoinWait = Integer.parseInt(value); break; case contextroot: + if (contextRoot != null) { LOGGER.warning("Multiple --contextroot arguments only the last one will apply"); } @@ -1377,6 +1378,7 @@ else if (requestTracing[0].matches("\\D+")) { if (contextRoot.equals("ROOT")) { contextRoot = "/"; } + LOGGER.log(Level.INFO, "Context Root: " + contextRoot); break; default: break; @@ -1394,37 +1396,36 @@ private void configureRequestTracingService() { preBootCommands.add(new BootCommand("set", "configs.config.server-config.request-tracing-service-configuration.threshold-unit=" - + requestTracingThresholdUnit)); + + requestTracingThresholdUnit)); preBootCommands.add(new BootCommand("set", "configs.config.server-config.request-tracing-service-configuration.threshold-value" + "=" - + Long.toString(requestTracingThresholdValue))); + + Long.toString(requestTracingThresholdValue))); if (enableRequestTracingAdaptiveSampling) { preBootCommands.add(new BootCommand("set", "configs.config.server-config.request-tracing-service-configuration.adaptive-sampling-enabled=" - + Boolean.toString(enableRequestTracingAdaptiveSampling))); + + Boolean.toString(enableRequestTracingAdaptiveSampling))); preBootCommands.add(new BootCommand("set", "configs.config.server-config.request-tracing-service-configuration.adaptive-sampling-target-count=" - + Integer.toString(requestTracingAdaptiveSamplingTargetCount))); + + Integer.toString(requestTracingAdaptiveSamplingTargetCount))); preBootCommands.add(new BootCommand("set", "configs.config.server-config.request-tracing-service-configuration.adaptive-sampling-time-value=" - + Integer.toString(requestTracingAdaptiveSamplingTimeValue))); + + Integer.toString(requestTracingAdaptiveSamplingTimeValue))); preBootCommands.add(new BootCommand("set", "configs.config.server-config.request-tracing-service-configuration.adaptive-sampling-time-unit=" - + requestTracingAdaptiveSamplingTimeUnit)); + + requestTracingAdaptiveSamplingTimeUnit)); } } } /** - * Process the user system properties in precedence - * 1st loads the properties from the uber jar location - * then loads each command line system properties file which will override - * uber jar properties + * Process the user system properties in precedence 1st loads the properties + * from the uber jar location then loads each command line system properties + * file which will override uber jar properties * * @param options * @throws IllegalArgumentException @@ -1437,7 +1438,7 @@ private void processUserProperties(RuntimeOptions options) throws IllegalArgumen Properties props = new Properties(); props.load(is); for (Map.Entry entry : props.entrySet()) { - userSystemProperties.setProperty((String)entry.getKey(), (String)entry.getValue()); + userSystemProperties.setProperty((String) entry.getKey(), (String) entry.getValue()); } } } catch (IOException ex) { @@ -1474,22 +1475,24 @@ private void processUserProperties(RuntimeOptions options) throws IllegalArgumen } private void deployAll() throws GlassFishException { - // Deploy from within the jar first. int deploymentCount = 0; Deployer deployer = gf.getDeployer(); - + // load context roots from uber jar try (InputStream is = this.getClass().getClassLoader().getResourceAsStream(CONTEXT_PROPS_FILE)) { if (is != null) { + Properties props = new Properties(); props.load(is); + for (Map.Entry entry : props.entrySet()) { if (contextRoots == null) { contextRoots = new Properties(); } - contextRoots.setProperty((String)entry.getKey(), (String)entry.getValue()); + contextRoots.setProperty((String) entry.getKey(), (String) entry.getValue()); } + } } catch (IOException ex) { LOGGER.log(Level.SEVERE, "", ex); @@ -1524,14 +1527,14 @@ private void deployAll() throws GlassFishException { if (deployContext.equals("ROOT")) { deployContext = "/"; } - + if (contextRoots != null && contextRoots.containsKey(file.getName())) { deployContext = contextRoots.getProperty(file.getName()); } + deployer.deploy(this.getClass().getClassLoader().getResourceAsStream(entry), "--availabilityenabled", + "true", "--contextroot", + deployContext, "--name", name, "--force", "true", "--loadOnly", "true"); - deployer.deploy(this.getClass().getClassLoader().getResourceAsStream(entry), "--availabilityenabled", - "true", "--contextroot", - deployContext, "--name", name, "--force","true", "--loadOnly", "true"); deploymentCount++; } } catch (IOException ioe) { @@ -1554,11 +1557,17 @@ private void deployAll() throws GlassFishException { contextRoot = null; } if (war.exists() && war.canRead()) { + if (war.getName().startsWith("ROOT.")) { deployer.deploy(war, "--availabilityenabled=true", "--force=true", "--contextroot=/", "--loadOnly", "true"); } else { - deployer.deploy(war, "--availabilityenabled=true", "--force=true", "--loadOnly", "true", "--contextroot", deployContext); + if(deployContext == null) { + deployer.deploy(war, "--availabilityenabled=true", "--force=true", "--loadOnly", "true"); + } else { + deployer.deploy(war, "--availabilityenabled=true", "--force=true", "--loadOnly", "true", "--contextroot", deployContext); + } } + deploymentCount++; } else { LOGGER.log(Level.WARNING, "{0} is not a valid deployment", war.getAbsolutePath()); @@ -1568,11 +1577,11 @@ private void deployAll() throws GlassFishException { // Deploy from deployment directory if (deploymentRoot != null) { - + // Get all files in the directory, and sort them by file type List deploymentDirEntries = Arrays.asList(deploymentRoot.listFiles()); deploymentDirEntries.sort(new DeploymentComparator()); - + for (File entry : deploymentDirEntries) { String entryPath = entry.getAbsolutePath(); if (entry.isFile() && entry.canRead() && (entryPath.endsWith(".war") || entryPath.endsWith(".ear") || entryPath.endsWith(".jar") || entryPath.endsWith(".rar"))) { @@ -1587,7 +1596,11 @@ private void deployAll() throws GlassFishException { if (entry.getName().startsWith("ROOT.")) { deployer.deploy(entry, "--availabilityenabled=true", "--force=true", "--contextroot=/", "--loadOnly", "true"); } else { - deployer.deploy(entry, "--availabilityenabled=true", "--force=true", "--loadOnly", "true", "--contextroot",deployContext); + if(deployContext == null) { + deployer.deploy(entry, "--availabilityenabled=true", "--force=true", "--loadOnly", "true"); + } else { + deployer.deploy(entry, "--availabilityenabled=true", "--force=true", "--loadOnly", "true", "--contextroot", deployContext); + } } deploymentCount++; } @@ -1659,21 +1672,21 @@ private void resetLogging() { } System.setProperty("java.util.logging.config.file", runtimeDir.getLoggingProperties().getAbsolutePath()); - try (InputStream is = new FileInputStream(runtimeDir.getLoggingProperties())){ + try (InputStream is = new FileInputStream(runtimeDir.getLoggingProperties())) { LogManager.getLogManager().readConfiguration(is); - + // go through all root handlers and set formatters based on properties Logger rootLogger = LogManager.getLogManager().getLogger(""); for (Handler handler : rootLogger.getHandlers()) { - String formatter = LogManager.getLogManager().getProperty(handler.getClass().getCanonicalName()+".formatter"); + String formatter = LogManager.getLogManager().getProperty(handler.getClass().getCanonicalName() + ".formatter"); if (formatter != null) { handler.setFormatter((Formatter) Class.forName(formatter).newInstance()); } } - + } catch (SecurityException | IOException | ClassNotFoundException | InstantiationException | IllegalAccessException ex) { LOGGER.log(Level.SEVERE, "Unable to reset the log manager", ex); - } + } } else { // system property was not set on the command line using the command option or via -D // we are likely using our default properties file so see if we need to rewrite it if (logToFile) { @@ -1704,7 +1717,7 @@ private void resetLogging() { } } System.setProperty("java.util.logging.config.file", runtimeDir.getLoggingProperties().getAbsolutePath()); - try (InputStream is = new FileInputStream(runtimeDir.getLoggingProperties())){ + try (InputStream is = new FileInputStream(runtimeDir.getLoggingProperties())) { LogManager.getLogManager().readConfiguration(is); // reset the formatters on the two handlers @@ -1834,12 +1847,12 @@ private void configurePorts() throws GlassFishException { preBootCommands.add(new BootCommand("set", "configs.config.server-config.network-config.network-listeners.network-listener.https-listener.port-range=" + Integer.toString(minPort) + "," + Integer.toString(maxPort))); preBootCommands.add(new BootCommand("set", "configs.config.server-config.network-config.network-listeners.network-listener.https-listener.enabled=true")); } - + if (sniEnabled) { preBootCommands.add(new BootCommand("set", "configs.config.server-config.network-config.protocols.protocol.https-listener.ssl.sni-enabled=true")); } if (sslCert != null) { - preBootCommands.add(new BootCommand("set", "configs.config.server-config.network-config.protocols.protocol.https-listener.ssl.cert-nickname=" + sslCert)); + preBootCommands.add(new BootCommand("set", "configs.config.server-config.network-config.protocols.protocol.https-listener.ssl.cert-nickname=" + sslCert)); } } @@ -1850,14 +1863,13 @@ private void configurePhoneHome() { } } - private void configureHazelcast() { // check hazelcast cluster overrides // set join wait based on the command flag if (System.getProperty("hazelcast.wait.seconds.before.join") == null) { System.setProperty("hazelcast.wait.seconds.before.join", Integer.toString(initialJoinWait)); } - + if (noCluster) { preBootCommands.add(new BootCommand("set", "configs.config.server-config.hazelcast-config-specific-configuration.enabled=false")); preBootCommands.add(new BootCommand("set", "configs.config.server-config.ejb-container.ejb-timer-service.ejb-timer-service=Dummy")); @@ -1896,12 +1908,12 @@ private void configureHazelcast() { if (instanceGroup != null) { preBootCommands.add(new BootCommand("set", "configs.config.server-config.hazelcast-config-specific-configuration.member-group=" + instanceGroup)); } - + if (publicAddress != null && !publicAddress.isEmpty()) { - preBootCommands.add(new BootCommand("set", "configs.config.server-config.hazelcast-config-specific-configuration.public-address=" + publicAddress)); + preBootCommands.add(new BootCommand("set", "configs.config.server-config.hazelcast-config-specific-configuration.public-address=" + publicAddress)); } preBootCommands.add(new BootCommand("set", "hazelcast-runtime-configuration.host-aware-partitioning=" + hostAware)); - + if (clustermode != null) { if (clustermode.startsWith("tcpip:")) { String tcpipmembers = clustermode.substring(6); @@ -1914,7 +1926,7 @@ private void configureHazelcast() { preBootCommands.add(new BootCommand("set", "hazelcast-runtime-configuration.multicast-port=" + hostPort[2])); preBootCommands.add(new BootCommand("set", "hazelcast-runtime-configuration.discovery-mode=multicast")); } - } else if (clustermode.startsWith("domain:")) { + } else if (clustermode.startsWith("domain:")) { String hostPort[] = clustermode.split(":"); if (hostPort.length == 3) { preBootCommands.add(new BootCommand("set", "hazelcast-runtime-configuration.das-public-address=" + hostPort[1])); @@ -1936,11 +1948,11 @@ private void configureHazelcast() { preBootCommands.add(new BootCommand("set", "hazelcast-runtime-configuration.discovery-mode=dns")); } } else { - preBootCommands.add(new BootCommand("set", "hazelcast-runtime-configuration.discovery-mode=multicast")); + preBootCommands.add(new BootCommand("set", "hazelcast-runtime-configuration.discovery-mode=multicast")); } - + if (interfaces != null) { - preBootCommands.add(new BootCommand("set", "hazelcast-runtime-configuration.interface=" + interfaces)); + preBootCommands.add(new BootCommand("set", "hazelcast-runtime-configuration.interface=" + interfaces)); } } } @@ -1978,8 +1990,6 @@ void generateLogo() { */ private void getGAVURLs() throws GlassFishException { GAVConvertor gavConvertor = new GAVConvertor(); - - for (String gav : GAVs) { try { @@ -1995,6 +2005,7 @@ private void getGAVURLs() throws GlassFishException { defaultContext = "/"; } } else { + LOGGER.log(Level.SEVERE, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CONTEXT ROOT SET TO NULL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); defaultContext = this.contextRoot; contextRoot = null; // use only once } @@ -2136,7 +2147,7 @@ private void setArgumentsFromSystemProperties() { autoBindHttp = getBooleanProperty("payaramicro.autoBindHttp"); autoBindRange = getIntegerProperty("payaramicro.autoBindRange", 5); - initialJoinWait = getIntegerProperty("payaramicro.initialJoinWait",1); + initialJoinWait = getIntegerProperty("payaramicro.initialJoinWait", 1); autoBindSsl = getBooleanProperty("payaramicro.autoBindSsl"); generateLogo = getBooleanProperty("payaramicro.logo"); logToFile = getBooleanProperty("payaramicro.logToFile"); @@ -2150,7 +2161,7 @@ private void setArgumentsFromSystemProperties() { sniEnabled = getBooleanProperty("payaramicro.sniEnabled"); hzMulticastGroup = getProperty("payaramicro.mcAddress"); hzPort = getIntegerProperty("payaramicro.mcPort", Integer.MIN_VALUE); - hostAware = getBooleanProperty("payaramicro.hostAware","true"); + hostAware = getBooleanProperty("payaramicro.hostAware", "true"); hzStartPort = getIntegerProperty("payaramicro.startPort", Integer.MIN_VALUE); hzClusterName = getProperty("payaramicro.clusterName"); hzClusterPassword = getProperty("payaramicro.clusterPassword"); @@ -2219,8 +2230,8 @@ private void packageUberJar() { } } - if (libraries != null){ - for (File lib : libraries){ + if (libraries != null) { + for (File lib : libraries) { creator.addLibraryJar(lib); } } @@ -2232,7 +2243,7 @@ private void packageUberJar() { if (copyDirectory != null) { creator.setDirectoryToCopy(copyDirectory); } - + creator.setContextRoots(contextRoots); if (GAVs != null) { @@ -2297,11 +2308,11 @@ private void packageUberJar() { if (hzClusterPassword != null) { props.setProperty("payaramicro.clusterPassword", hzClusterPassword); } - + if (clustermode != null) { props.setProperty("payaramicro.clusterMode", clustermode); } - + if (interfaces != null) { props.setProperty("payaramicro.interfaces", interfaces); } @@ -2309,11 +2320,11 @@ private void packageUberJar() { if (secretsDir != null) { props.setProperty("payaramicro.secretsDir", secretsDir); } - + if (sslCert != null) { props.setProperty("payaramicro.sslCert", sslCert); } - + if (contextRoot != null) { props.setProperty("payaramicro.contextRoot", contextRoot); } @@ -2334,7 +2345,7 @@ private void packageUberJar() { props.setProperty("payaramicro.showServletMappings", Boolean.toString(showServletMappings)); props.setProperty("payaramicro.sniEnabled", Boolean.toString(sniEnabled)); props.setProperty("payaramicro.initialJoinWait", Integer.toString(initialJoinWait)); - + if (publicAddress != null) { props.setProperty("payaramicro.publicAddress", publicAddress); } @@ -2518,7 +2529,7 @@ private static void setBootProperties() { LOGGER.log(Level.WARNING, "Could not load the boot system properties from " + BOOT_PROPS_FILE, ioe); } } - + private void configureNotificationService() { if (enableHealthCheck || enableRequestTracing) { preBootCommands.add(new BootCommand("set", "configs.config.server-config.notification-service-configuration.enabled=true")); @@ -2621,7 +2632,6 @@ private static boolean getBooleanProperty(String value, String defaultValue) { return "true".equals(property); } - private static int getIntegerProperty(String value, int defaultValue) { String property; property = System.getProperty(value); @@ -2679,7 +2689,7 @@ public PayaraMicroImpl addLibrary(File lib) { private void configureSecrets() { if (secretsDir != null) { - preBootCommands.add(new BootCommand("set", "configs.config.server-config.microprofile-config.secret-dir=" + secretsDir)); + preBootCommands.add(new BootCommand("set", "configs.config.server-config.microprofile-config.secret-dir=" + secretsDir)); } } From f7a6942c5b5e82b7563466962d06b75e217ac4e1 Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Wed, 13 Mar 2019 13:34:27 +0000 Subject: [PATCH 022/108] removed testing comments --- .../java/fish/payara/micro/boot/PayaraMicroLauncher.java | 5 ----- .../main/java/fish/payara/micro/impl/PayaraMicroImpl.java | 2 -- 2 files changed, 7 deletions(-) diff --git a/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/PayaraMicroLauncher.java b/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/PayaraMicroLauncher.java index 1a797f9cbe0..a9d3793decb 100644 --- a/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/PayaraMicroLauncher.java +++ b/appserver/extras/payara-micro/payara-micro-boot/src/main/java/fish/payara/micro/boot/PayaraMicroLauncher.java @@ -69,11 +69,6 @@ public class PayaraMicroLauncher extends ExecutableArchiveLauncher { * @throws Exception */ public static void main(String args[]) throws Exception { - System.out.println("########################################################################################"); - for(String arg : args) { - System.out.println(arg); - } - System.out.println("########################################################################################"); create("main", args); } diff --git a/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java b/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java index 90869c91d81..a82f18caad1 100644 --- a/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java +++ b/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java @@ -1378,7 +1378,6 @@ else if (requestTracing[0].matches("\\D+")) { if (contextRoot.equals("ROOT")) { contextRoot = "/"; } - LOGGER.log(Level.INFO, "Context Root: " + contextRoot); break; default: break; @@ -2005,7 +2004,6 @@ private void getGAVURLs() throws GlassFishException { defaultContext = "/"; } } else { - LOGGER.log(Level.SEVERE, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CONTEXT ROOT SET TO NULL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); defaultContext = this.contextRoot; contextRoot = null; // use only once } From 15a5fe2fd1c338112c2d0a9cc1c6281056eca77f Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Wed, 13 Mar 2019 15:11:10 +0100 Subject: [PATCH 023/108] PAYARA-3466 addressed formatting issue --- .../openapi/impl/processor/ApplicationProcessor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java index 9f908c1433e..7d81b251f8c 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java @@ -407,8 +407,8 @@ public void visitFormParam(FormParam param, AnnotatedElement element, ApiContext // Set the request body type accordingly. context.getWorkingOperation().getRequestBody().getContent() - .getMediaType(javax.ws.rs.core.MediaType.WILDCARD).getSchema() - .setType(formSchemaType); + .getMediaType(javax.ws.rs.core.MediaType.WILDCARD).getSchema() + .setType(formSchemaType); } } From d0bbc63922d06d606d80eeef7872b886be463f2e Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Wed, 13 Mar 2019 15:39:26 +0100 Subject: [PATCH 024/108] PAYARA-3466 reverted logic in getParentSchemaType --- .../microprofile/openapi/impl/model/util/ModelUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java index 1f58455efc8..a0202bc73df 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java @@ -313,6 +313,12 @@ public static SchemaType getParentSchemaType(SchemaType type1, SchemaType type2) if (type2 == null) { return type1; } + if (type1 == SchemaType.OBJECT || type2 == SchemaType.OBJECT) { + return SchemaType.OBJECT; + } + if (type1 == SchemaType.STRING || type2 == SchemaType.STRING) { + return SchemaType.STRING; + } if (type1 != type2) { return SchemaType.STRING; } From a64910342e050d23b8a751e18a4a9a32aa005f00 Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Wed, 13 Mar 2019 16:33:49 +0000 Subject: [PATCH 025/108] Created initial parameter to track contextroot label being applied --- .../payara/micro/impl/PayaraMicroImpl.java | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java b/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java index a82f18caad1..e8ca8995207 100644 --- a/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java +++ b/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java @@ -1477,6 +1477,7 @@ private void deployAll() throws GlassFishException { // Deploy from within the jar first. int deploymentCount = 0; Deployer deployer = gf.getDeployer(); + boolean hasDefinedContextRoot = (contextRoot != null && contextRoot.isEmpty() == false); // load context roots from uber jar try (InputStream is = this.getClass().getClassLoader().getResourceAsStream(CONTEXT_PROPS_FILE)) { @@ -1546,24 +1547,24 @@ private void deployAll() throws GlassFishException { // Deploy command line provided files if (deployments != null) { - for (File war : deployments) { - String deployContext = war.getName().substring(0, war.getName().length() - 4); - if (contextRoots != null && contextRoots.containsKey(war.getName())) { - deployContext = contextRoots.getProperty(war.getName()); - } else if (contextRoot != null) { - deployContext = contextRoot; - // unset so only used once - contextRoot = null; - } - if (war.exists() && war.canRead()) { - + for (File war : deployments) { + if (war.exists() && war.canRead()) { + String deployContext = war.getName().substring(0, war.getName().length() - 4); + if (contextRoots != null && contextRoots.containsKey(war.getName())) { + deployContext = contextRoots.getProperty(war.getName()); + } else if (contextRoot != null) { + deployContext = contextRoot; + //unset so only used once + contextRoot = null; + } + if (war.getName().startsWith("ROOT.")) { deployer.deploy(war, "--availabilityenabled=true", "--force=true", "--contextroot=/", "--loadOnly", "true"); } else { - if(deployContext == null) { - deployer.deploy(war, "--availabilityenabled=true", "--force=true", "--loadOnly", "true"); - } else { + if (hasDefinedContextRoot) { deployer.deploy(war, "--availabilityenabled=true", "--force=true", "--loadOnly", "true", "--contextroot", deployContext); + } else { + deployer.deploy(war, "--availabilityenabled=true", "--force=true", "--loadOnly", "true"); } } @@ -1585,20 +1586,20 @@ private void deployAll() throws GlassFishException { String entryPath = entry.getAbsolutePath(); if (entry.isFile() && entry.canRead() && (entryPath.endsWith(".war") || entryPath.endsWith(".ear") || entryPath.endsWith(".jar") || entryPath.endsWith(".rar"))) { String deployContext = entry.getName().substring(0, entry.getName().length() - 4); - if (contextRoots != null && contextRoots.containsKey(entry.getName())) { - deployContext = contextRoots.getProperty(entry.getName()); - } else if (contextRoot != null) { - deployContext = contextRoot; - // unset so only used once - contextRoot = null; + if (contextRoots != null && contextRoots.containsKey(entry.getName())) { + deployContext = contextRoots.getProperty(entry.getName()); + } else if (contextRoot != null) { + deployContext = contextRoot; + // unset so only used once + contextRoot = null; } if (entry.getName().startsWith("ROOT.")) { deployer.deploy(entry, "--availabilityenabled=true", "--force=true", "--contextroot=/", "--loadOnly", "true"); } else { - if(deployContext == null) { - deployer.deploy(entry, "--availabilityenabled=true", "--force=true", "--loadOnly", "true"); - } else { + if (hasDefinedContextRoot) { deployer.deploy(entry, "--availabilityenabled=true", "--force=true", "--loadOnly", "true", "--contextroot", deployContext); + } else { + deployer.deploy(entry, "--availabilityenabled=true", "--force=true", "--loadOnly", "true"); } } deploymentCount++; From 010900245dbe926f733633a1e10db0f353ea1ad2 Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Thu, 14 Mar 2019 09:04:30 +0000 Subject: [PATCH 026/108] changed placement to support multiple deployments --- .../main/java/fish/payara/micro/impl/PayaraMicroImpl.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java b/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java index e8ca8995207..497da75af72 100644 --- a/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java +++ b/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java @@ -1477,7 +1477,6 @@ private void deployAll() throws GlassFishException { // Deploy from within the jar first. int deploymentCount = 0; Deployer deployer = gf.getDeployer(); - boolean hasDefinedContextRoot = (contextRoot != null && contextRoot.isEmpty() == false); // load context roots from uber jar try (InputStream is = this.getClass().getClassLoader().getResourceAsStream(CONTEXT_PROPS_FILE)) { @@ -1548,6 +1547,9 @@ private void deployAll() throws GlassFishException { // Deploy command line provided files if (deployments != null) { for (File war : deployments) { + + boolean hasDefinedContextRoot = (contextRoot != null && contextRoot.isEmpty() == false); + if (war.exists() && war.canRead()) { String deployContext = war.getName().substring(0, war.getName().length() - 4); if (contextRoots != null && contextRoots.containsKey(war.getName())) { @@ -1583,6 +1585,9 @@ private void deployAll() throws GlassFishException { deploymentDirEntries.sort(new DeploymentComparator()); for (File entry : deploymentDirEntries) { + + boolean hasDefinedContextRoot = (contextRoot != null && contextRoot.isEmpty() == false); + String entryPath = entry.getAbsolutePath(); if (entry.isFile() && entry.canRead() && (entryPath.endsWith(".war") || entryPath.endsWith(".ear") || entryPath.endsWith(".jar") || entryPath.endsWith(".rar"))) { String deployContext = entry.getName().substring(0, entry.getName().length() - 4); From 7aea90bdd1835199caece7293ace54050025d8ec Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Thu, 14 Mar 2019 12:23:43 +0000 Subject: [PATCH 027/108] Created Deprecated package duplicates --- .../rest/admin/DisableEjbInvokerCommand.java | 129 ++++++ .../rest/admin/EnableEjbInvokerCommand.java | 130 ++++++ .../ejb/rest/client/EjbRestProxyFactory.java | 87 ++++ .../ejb/rest/client/EjbRestProxyHandler.java | 154 +++++++ .../ejb/rest/client/RemoteEJBContext.java | 388 ++++++++++++++++++ .../rest/client/RemoteEJBContextFactory.java | 86 ++++ 6 files changed, 974 insertions(+) create mode 100644 appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java create mode 100644 appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java create mode 100644 appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java create mode 100644 appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java create mode 100644 appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java create mode 100644 appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java diff --git a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java new file mode 100644 index 00000000000..ffea8c0acf7 --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java @@ -0,0 +1,129 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.ejb.rest.admin; + +import static org.glassfish.config.support.CommandTarget.CLUSTER; +import static org.glassfish.config.support.CommandTarget.CLUSTERED_INSTANCE; +import static org.glassfish.config.support.CommandTarget.CONFIG; +import static org.glassfish.config.support.CommandTarget.DAS; +import static org.glassfish.config.support.CommandTarget.DEPLOYMENT_GROUP; +import static org.glassfish.config.support.CommandTarget.STANDALONE_INSTANCE; +import static org.glassfish.deployment.autodeploy.AutoDeployer.getNameFromFilePath; + +import java.nio.file.Path; + +import javax.inject.Inject; + +import com.sun.enterprise.config.serverbeans.Domain; +import org.glassfish.api.ActionReport; +import org.glassfish.api.Param; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.RuntimeType; +import org.glassfish.api.admin.ServerEnvironment; +import org.glassfish.config.support.TargetType; +import org.glassfish.deployment.autodeploy.AutoDeployer.AutodeploymentStatus; +import org.glassfish.deployment.autodeploy.AutoUndeploymentOperation; +import org.glassfish.hk2.api.PerLookup; +import org.glassfish.hk2.api.ServiceLocator; +import org.jvnet.hk2.annotations.Service; + +/** + * This command disables the EJB invoker endpoint. + * + *

+ * This happens by undeploying the small application in /domains/[domain]/endpoints/ejb-invoker. + * Note that by default this application is not deployed. The default context root of this application is + * /ejb-invoker, but it may have been set to a different root by the {@link EnableEjbInvokerCommand} + * command. + * + * @author Arjan Tijms + * + */ +@Deprecated +@Service(name = "disable-ejb-invoker") +@PerLookup +@ExecuteOn(RuntimeType.DAS) +@TargetType({ DAS, STANDALONE_INSTANCE, CLUSTER, CLUSTERED_INSTANCE, CONFIG, DEPLOYMENT_GROUP }) +public class DisableEjbInvokerCommand implements AdminCommand { + + private final String ENDPOINTS = "endpoints"; + private final String EJB_INVOKER = "ejb-invoker"; + + @Param(optional = true) + public String target; + + @Inject + private ServerEnvironment serverEnvironment; + + @Inject + private ServiceLocator serviceLocator; + + @Inject + private Domain domain; + + @Override + public void execute(AdminCommandContext context) { + + Path endPointsPath = serverEnvironment.getInstanceRoot().toPath().resolve(ENDPOINTS); + Path ejbInvokerPath = endPointsPath.resolve(EJB_INVOKER); + + AutoUndeploymentOperation autoUndeploymentOperation = AutoUndeploymentOperation.newInstance( + serviceLocator, + ejbInvokerPath.toFile(), + getNameFromFilePath(endPointsPath.toFile(), ejbInvokerPath.toFile()), + target); + + AutodeploymentStatus deploymentStatus = autoUndeploymentOperation.run(); + + ActionReport report = context.getActionReport(); + report.setActionExitCode(deploymentStatus.getExitCode()); + + if (deploymentStatus.getExitCode().equals(ActionReport.ExitCode.FAILURE)) { + if (domain.getApplications().getApplication("ejb-invoker") == null) { + report.appendMessage("\nEJB Invoker is not enabled on any target"); + } else { + report.appendMessage("\nFailed to disable Ejb Invoker - was it enabled on the specified target?"); + } + } + } + +} diff --git a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java new file mode 100644 index 00000000000..a23e1f687f6 --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java @@ -0,0 +1,130 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.ejb.rest.admin; + +import static org.glassfish.config.support.CommandTarget.CLUSTER; +import static org.glassfish.config.support.CommandTarget.CLUSTERED_INSTANCE; +import static org.glassfish.config.support.CommandTarget.CONFIG; +import static org.glassfish.config.support.CommandTarget.DAS; +import static org.glassfish.config.support.CommandTarget.DEPLOYMENT_GROUP; +import static org.glassfish.config.support.CommandTarget.STANDALONE_INSTANCE; + +import javax.inject.Inject; + +import com.sun.enterprise.config.serverbeans.Domain; +import org.glassfish.api.ActionReport; +import org.glassfish.api.Param; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.RuntimeType; +import org.glassfish.api.admin.ServerEnvironment; +import org.glassfish.config.support.TargetType; +import org.glassfish.deployment.autodeploy.AutoDeployer.AutodeploymentStatus; +import org.glassfish.deployment.autodeploy.AutoDeploymentOperation; +import org.glassfish.hk2.api.PerLookup; +import org.glassfish.hk2.api.ServiceLocator; +import org.jvnet.hk2.annotations.Service; + +/** + * This command enables the EJB invoker endpoint and optionally allows it to set an + * alternative context root. + * + *

+ * This happens by the deploying a small application in /domains/[domain]/endpoints/ejb-invoker + * which by default is not deployed. The default context root of this application is + * /ejb-invoker. + * + * @author Arjan Tijms + * + */ +@Deprecated +@Service(name = "enable-ejb-invoker") +@PerLookup +@ExecuteOn(RuntimeType.DAS) +@TargetType({ DAS, STANDALONE_INSTANCE, CLUSTER, CLUSTERED_INSTANCE, CONFIG, DEPLOYMENT_GROUP }) +public class EnableEjbInvokerCommand implements AdminCommand { + + private final String ENDPOINT = "endpoints/ejb-invoker"; + + @Param(name = "contextRoot", primary = true, optional = true) + private String contextRoot; + + @Param(optional = true) + public String target; + + @Inject + private ServerEnvironment serverEnvironment; + + @Inject + private ServiceLocator serviceLocator; + + @Inject + private Domain domain; + + @Override + public void execute(AdminCommandContext context) { + AutoDeploymentOperation autoDeploymentOperation = AutoDeploymentOperation.newInstance( + serviceLocator, + serverEnvironment.getInstanceRoot().toPath().resolve(ENDPOINT).toFile(), + getDefaultVirtualServer(), + target, + contextRoot + ); + + if (domain.getApplications().getApplication("ejb-invoker") == null) { + AutodeploymentStatus deploymentStatus = autoDeploymentOperation.run(); + ActionReport report = context.getActionReport(); + report.setActionExitCode(deploymentStatus.getExitCode()); + } else { + ActionReport report = context.getActionReport(); + report.setActionExitCode(ActionReport.ExitCode.WARNING); + report.setMessage("EJB Invoker is already deployed on at least one target, please edit it as you would a " + + "normal application using the create-application-ref, delete-application-ref, " + + "or update-application-ref commands"); + } + } + + private String getDefaultVirtualServer() { + // XXX write this? + return null; + } + +} diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java new file mode 100644 index 00000000000..3c86fd587ca --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyFactory.java @@ -0,0 +1,87 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.ejb.rest.client; + +import static java.lang.reflect.Proxy.newProxyInstance; +import static java.security.AccessController.doPrivileged; +import static java.util.Collections.emptyList; +import static org.glassfish.jersey.internal.util.ReflectionHelper.getClassLoaderPA; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Cookie; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; + +/** + * This class generates a type-safe proxy for a given remote EJB interface. + * + *

+ * Calls on this proxy are handled by {@link EjbRestProxyHandler}. + * + * + * @author Arjan Tijms + * @since Payara 5.191 + * + */ +@Deprecated +final class EjbRestProxyFactory { + + private static final MultivaluedMap EMPTY_MULTI_MAP = new MultivaluedHashMap<>(); + + public static C newProxy(Class remoteBusinessInterface, WebTarget target, String lookup, Map jndiOptions) { + return newProxy(remoteBusinessInterface, target, EMPTY_MULTI_MAP, emptyList(), lookup, jndiOptions); + } + + @SuppressWarnings("unchecked") + public static C newProxy(Class remoteBusinessInterface, WebTarget target, MultivaluedMap headers, List cookies, String lookup, Map jndiOptions) { + return (C) + newProxyInstance(doPrivileged(getClassLoaderPA(remoteBusinessInterface)), + new Class[] { remoteBusinessInterface }, + new EjbRestProxyHandler(addPathFromClass(remoteBusinessInterface, target), headers, cookies, lookup, jndiOptions)); + } + + private static WebTarget addPathFromClass(Class clazz, WebTarget target) { + return target.path(clazz.getSimpleName()); + } + +} diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java new file mode 100644 index 00000000000..a8ab6b36e28 --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/EjbRestProxyHandler.java @@ -0,0 +1,154 @@ +package fish.payara.ejb.rest.client; + +import static javax.naming.Context.SECURITY_CREDENTIALS; +import static javax.naming.Context.SECURITY_PRINCIPAL; +import static javax.ws.rs.HttpMethod.POST; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.util.Base64; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Future; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Cookie; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; + +/** + * This class handles invocations (method calls) on a proxy generated by {@link EjbRestProxyFactory}. + * + *

+ * This proxy uses REST calls to an endpoint in a given remote Payara server. + * + * @author Arjan Tijms + * @since Payara 5.191 + * + */ +@Deprecated +class EjbRestProxyHandler implements InvocationHandler { + + private final WebTarget target; + private final MultivaluedMap headers; + private final List cookies; + private final String lookup; + private final Map jndiOptions; + + EjbRestProxyHandler(WebTarget target, MultivaluedMap headers, List cookies, String lookup, Map jndiOptions) { + this.target = target; + this.headers = headers; + this.cookies = cookies; + this.lookup = lookup; + this.jndiOptions = jndiOptions; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] argValues) throws Throwable { + + // Check for methods we should not proxy first + + if (argValues == null && method.getName().equals("toString")) { + return toString(); + } + + if (argValues == null && method.getName().equals("hashCode")) { + // unique instance in the JVM, and no need to override + return hashCode(); + } + + if (argValues != null && argValues.length == 1 && method.getName().equals("equals")) { + // unique instance in the JVM, and no need to override + return equals(argValues[0]); + } + + // Valid method, do invoke it remotely + return doRemoteInvoke(proxy, method, argValues); + } + + public Object doRemoteInvoke(Object proxy, Method method, Object[] argValues) throws Throwable { + // HTTP method name; we're always using POST to invoke remote EJBs + String httpMethod = POST; + + // The bare payload being sent + Map payload = new HashMap<>(); + payload.put("lookup", lookup); + payload.put("method", method.getName()); + payload.put("argTypes", method.getParameterTypes()); + payload.put("argValues", argValues == null? new Object[0] : argValues); + + if (jndiOptions.containsKey(SECURITY_PRINCIPAL)) { + payload.put(SECURITY_PRINCIPAL, base64Encode(jndiOptions.get(SECURITY_PRINCIPAL))); + } + + if (jndiOptions.containsKey(SECURITY_CREDENTIALS)) { + payload.put(SECURITY_CREDENTIALS, base64Encode(jndiOptions.get(SECURITY_CREDENTIALS))); + } + + // Payload wrapped as entity so it'll be encoded in JSON + Entity entity = Entity.entity(payload, APPLICATION_JSON); + + // Response type + Class responseType = method.getReturnType(); + GenericType responseGenericType = new GenericType<>(method.getGenericReturnType()); + + // Create a new UriBuilder appending the name from the method + WebTarget newTarget = addPathFromMethod(method, target); + + // Start request + Invocation.Builder builder = newTarget.request(); + + // Set optional headers and cookies + builder.headers(new MultivaluedHashMap(this.headers)); + for (Cookie cookie : new LinkedList<>(this.cookies)) { + builder = builder.cookie(cookie); + } + + // Call remote server + + if (responseType.isAssignableFrom(CompletionStage.class)) { + + // Reactive call - the actual response type is T from CompletionStage + return builder.rx().method(httpMethod, entity, getResponseParameterizedType(method, responseGenericType)); + } else if (responseType.isAssignableFrom(Future.class)) { + + // Asynchronous call - the actual response type is T from Future + return builder.async().method(httpMethod, entity, getResponseParameterizedType(method, responseGenericType)); + } + + // Synchronous call + return builder.method(httpMethod, entity, responseGenericType); + } + + private GenericType getResponseParameterizedType(Method method, GenericType responseGenericType) { + if (method.getGenericReturnType() instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) method.getGenericReturnType(); + + return new GenericType<>(parameterizedType.getActualTypeArguments()[0]); + } + + return responseGenericType; + } + + private static String base64Encode(Object input) { + return Base64.getEncoder().encodeToString(input.toString().getBytes()); + } + + private static WebTarget addPathFromMethod(Method method, WebTarget target) { + return target.path(method.getName()); + } + + @Override + public String toString() { + return target.toString(); + } + +} diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java new file mode 100644 index 00000000000..22c733c1a5d --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java @@ -0,0 +1,388 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.ejb.rest.client; + +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_CONNECT_TIMEOUT; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_EXECUTOR_SERVICE; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_HOSTNAME_VERIFIER; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_KEY_STORE; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_READ_TIMEOUT; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_SSL_CONTEXT; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_TRUST_STORE; +import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_WITH_CONFIG; +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +import java.net.URI; +import java.net.URL; +import java.security.KeyStore; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledExecutorService; + +import javax.naming.Binding; +import javax.naming.Context; +import javax.naming.Name; +import javax.naming.NameClassPair; +import javax.naming.NameParser; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Configuration; + +/** + * This is the context used for looking up and invoking remote EJBs via + * REST in Payara 5.191+. + * + *

+ * Note that at the moment only the lookup methods are implemented. + * + *

+ * This context supports the following Payara specific properties in its environment: + * + *

    + *
  • fish.payara.connectTimeout
  • + *
  • fish.payara.executorService
  • + *
  • fish.payara.hostnameVerifier
  • + *
  • fish.payara.keyStore
  • + *
  • fish.payara.readTimeout
  • + *
  • fish.payara.hostnameVerifier
  • + *
  • fish.payara.scheduledExecutorService"
  • + *
  • fish.payara.sslContext
  • + *
  • fish.payara.trustStore
  • + *
  • fish.payara.withConfig
  • + *
+ * + * All properties corresponds to the similarly named settings on the JAX-RS {@link ClientBuilder}. + * Times are in microseconds, and values can either be given as Strings, number values or object instances. + * + * @author Arjan Tijms + * @since Payara 5.191 + * + */ +@Deprecated +class RemoteEJBContext implements Context { + + private Hashtable environment; + + @SuppressWarnings("unchecked") + public RemoteEJBContext(Hashtable environment) { + this.environment = (Hashtable) environment; + } + + @Override + public Object lookup(Name name) throws NamingException { + return lookup(name.toString()); + } + + @Override + public Object lookup(String name) throws NamingException { + String url = (String) environment.get(PROVIDER_URL); + + try { + // Get client build with all optional config applied + ClientBuilder clientBuilder = getClientBuilder(); + + // For the lookup do a call to the remote server first to obtain + // the remote business interface class name given a JNDI lookup name. + // The JNDI lookup name normally does not give us this interface name. + // This also allows us to check the JNDI name indeed resolves before + // we create a proxy and return it here. + + Map payload = new HashMap<>(); + payload.put("lookup", name); + + URI remotePayaraURI = new URL(url).toURI(); + + String className = + clientBuilder + .build() + .target(remotePayaraURI) + .path("ejb") + .path("lookup") + .request() + .post(Entity.entity(payload, APPLICATION_JSON)) + .readEntity(String.class); + + // After we have obtained the class name of the remote interface, generate + // a proxy based on it. + + return EjbRestProxyFactory.newProxy( + Class.forName(className), + clientBuilder.build() + .target(remotePayaraURI) + .path("ejb") + .path("invoke"), + name, + new HashMap(environment) + ); + + } catch (Exception e) { + throw newNamingException(name, e); + } + } + + private ClientBuilder getClientBuilder() throws ClassNotFoundException, InstantiationException, IllegalAccessException { + ClientBuilder clientBuilder = ClientBuilder.newBuilder(); + + if (environment.containsKey(FISH_PAYARA_CONNECT_TIMEOUT)) { + clientBuilder.connectTimeout(getLong(environment.get(FISH_PAYARA_CONNECT_TIMEOUT)).longValue(), MICROSECONDS); + } + + if (environment.contains(FISH_PAYARA_EXECUTOR_SERVICE)) { + clientBuilder.executorService(getInstance(environment.get(FISH_PAYARA_EXECUTOR_SERVICE), ExecutorService.class)); + } + + if (environment.contains(FISH_PAYARA_HOSTNAME_VERIFIER)) { + clientBuilder.hostnameVerifier(getInstance(environment.get(FISH_PAYARA_HOSTNAME_VERIFIER), HostnameVerifier.class)); + } + + if (environment.contains(FISH_PAYARA_KEY_STORE)) { + clientBuilder.keyStore(getInstance(environment.get(FISH_PAYARA_KEY_STORE), KeyStore.class), getPassword(environment.get("keyStorePassword"))); + } + + if (environment.containsKey(FISH_PAYARA_READ_TIMEOUT)) { + clientBuilder.readTimeout(getLong(environment.get(FISH_PAYARA_READ_TIMEOUT)).longValue(), MICROSECONDS); + } + + if (environment.contains(FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE)) { + clientBuilder.scheduledExecutorService(getInstance(environment.get(FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE), ScheduledExecutorService.class)); + } + + if (environment.contains(FISH_PAYARA_SSL_CONTEXT)) { + clientBuilder.sslContext(getInstance(environment.get(FISH_PAYARA_SSL_CONTEXT), SSLContext.class)); + } + + if (environment.contains(FISH_PAYARA_TRUST_STORE)) { + clientBuilder.trustStore(getInstance(environment.get(FISH_PAYARA_TRUST_STORE), KeyStore.class)); + } + + if (environment.contains(FISH_PAYARA_WITH_CONFIG)) { + clientBuilder.withConfig(getInstance(environment.get(FISH_PAYARA_WITH_CONFIG), Configuration.class)); + } + + return clientBuilder; + } + + private NamingException newNamingException(String name, Exception cause) { + NamingException namingException = new NamingException("Could not lookup :" + name); + namingException.initCause(cause); + + return namingException; + } + + private T getInstance(Object value, Class clazz) throws ClassNotFoundException, InstantiationException, IllegalAccessException { + if (clazz.isInstance(value)) { + return clazz.cast(value); + } + + if (value instanceof String) { + return clazz.cast(Class.forName((String)value).newInstance()); + } + + throw new IllegalStateException("Value " + value + " has to be of type String or " + clazz); + } + + private Long getLong(Object value) { + if (value instanceof Number) { + return ((Number) value).longValue(); + } + + if (value instanceof String) { + return Long.valueOf((String) value); + } + + throw new IllegalStateException("Value " + value + " has to be of type String or Number"); + } + + private char[] getPassword(Object value) { + if (value instanceof String) { + return ((String) value).toCharArray(); + } + + if (value instanceof char[]) { + return (char[]) value; + } + throw new IllegalArgumentException("No password provided"); + + } + + @Override + public void bind(Name name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void bind(String name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void rebind(Name name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void rebind(String name, Object obj) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void unbind(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void unbind(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void rename(Name oldName, Name newName) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void rename(String oldName, String newName) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NamingEnumeration list(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NamingEnumeration list(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NamingEnumeration listBindings(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NamingEnumeration listBindings(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void destroySubcontext(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public void destroySubcontext(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Context createSubcontext(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Context createSubcontext(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Object lookupLink(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Object lookupLink(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NameParser getNameParser(Name name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public NameParser getNameParser(String name) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Name composeName(Name name, Name prefix) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public String composeName(String name, String prefix) throws NamingException { + throw new UnsupportedOperationException(); + } + + @Override + public Object addToEnvironment(String propName, Object propVal) throws NamingException { + return environment.put(propName, propVal); + } + + @Override + public Object removeFromEnvironment(String propName) throws NamingException { + return environment.remove(propName); + } + + @Override + public Hashtable getEnvironment() throws NamingException { + return environment; + } + + @Override + public void close() throws NamingException { + environment.clear(); + } + + @Override + public String getNameInNamespace() throws NamingException { + throw new UnsupportedOperationException(); + } + +} diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java new file mode 100644 index 00000000000..ec46b95c54d --- /dev/null +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContextFactory.java @@ -0,0 +1,86 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.ejb.rest.client; + +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.spi.InitialContextFactory; + +/** + * This is the context factory that creates the context used for looking up and invoking + * remote EJBs. + * + *

+ * Clients wanting to use remote EJB in this way should set the property in the initial context + * environment as follows: + * + *

+ * 
+ *   Hashtable<String, String> environment = new Hashtable<>();
+ *   environment.put(INITIAL_CONTEXT_FACTORY, "fish.payara.ejb.rest.client.RemoteEJBContextFactory");
+ *    ...
+ *   new InitialContext(environment);
+ * 
+ * 
+ * + * @author Arjan Tijms + * @since Payara 5.191 + */ +@Deprecated +public class RemoteEJBContextFactory implements InitialContextFactory { + + public static final String FISH_PAYARA_WITH_CONFIG = "fish.payara.withConfig"; + public static final String FISH_PAYARA_TRUST_STORE = "fish.payara.trustStore"; + public static final String FISH_PAYARA_SSL_CONTEXT = "fish.payara.sslContext"; + public static final String FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE = "fish.payara.scheduledExecutorService"; + public static final String FISH_PAYARA_READ_TIMEOUT = "fish.payara.readTimeout"; + public static final String FISH_PAYARA_KEY_STORE = "fish.payara.keyStore"; + public static final String FISH_PAYARA_HOSTNAME_VERIFIER = "fish.payara.hostnameVerifier"; + public static final String FISH_PAYARA_EXECUTOR_SERVICE = "fish.payara.executorService"; + public static final String FISH_PAYARA_CONNECT_TIMEOUT = "fish.payara.connectTimeout"; + + @Override + public Context getInitialContext(Hashtable environment) throws NamingException { + return new RemoteEJBContext(environment); + } + +} From 1a724c586bc3bde37653ad477e07e7f04899f9dd Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Thu, 14 Mar 2019 12:24:48 +0000 Subject: [PATCH 028/108] Refactored http class names --- .../{EjbRestProxyFactory.java => EjbHttpProxyFactory.java} | 6 +++--- .../{EjbRestProxyHandler.java => EjbHttpProxyHandler.java} | 4 ++-- .../java/fish/payara/ejb/http/client/RemoteEJBContext.java | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) rename appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/{EjbRestProxyFactory.java => EjbHttpProxyFactory.java} (95%) rename appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/{EjbRestProxyHandler.java => EjbHttpProxyHandler.java} (97%) diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyFactory.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbHttpProxyFactory.java similarity index 95% rename from appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyFactory.java rename to appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbHttpProxyFactory.java index bfe40f8c287..e227f757fa0 100644 --- a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyFactory.java +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbHttpProxyFactory.java @@ -56,14 +56,14 @@ * This class generates a type-safe proxy for a given remote EJB interface. * *

- * Calls on this proxy are handled by {@link EjbRestProxyHandler}. + * Calls on this proxy are handled by {@link EjbHttpProxyHandler}. * * * @author Arjan Tijms * @since Payara 5.191 * */ -final class EjbRestProxyFactory { +final class EjbHttpProxyFactory { private static final MultivaluedMap EMPTY_MULTI_MAP = new MultivaluedHashMap<>(); @@ -76,7 +76,7 @@ public static C newProxy(Class remoteBusinessInterface, WebTarget target, return (C) newProxyInstance(doPrivileged(getClassLoaderPA(remoteBusinessInterface)), new Class[] { remoteBusinessInterface }, - new EjbRestProxyHandler(addPathFromClass(remoteBusinessInterface, target), headers, cookies, lookup, jndiOptions)); + new EjbHttpProxyHandler(addPathFromClass(remoteBusinessInterface, target), headers, cookies, lookup, jndiOptions)); } private static WebTarget addPathFromClass(Class clazz, WebTarget target) { diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyHandler.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbHttpProxyHandler.java similarity index 97% rename from appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyHandler.java rename to appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbHttpProxyHandler.java index 7aa0576d09e..1e10a98343f 100644 --- a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbRestProxyHandler.java +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/EjbHttpProxyHandler.java @@ -34,7 +34,7 @@ * @since Payara 5.191 * */ -class EjbRestProxyHandler implements InvocationHandler { +class EjbHttpProxyHandler implements InvocationHandler { private final WebTarget target; private final MultivaluedMap headers; @@ -42,7 +42,7 @@ class EjbRestProxyHandler implements InvocationHandler { private final String lookup; private final Map jndiOptions; - EjbRestProxyHandler(WebTarget target, MultivaluedMap headers, List cookies, String lookup, Map jndiOptions) { + EjbHttpProxyHandler(WebTarget target, MultivaluedMap headers, List cookies, String lookup, Map jndiOptions) { this.target = target; this.headers = headers; this.cookies = cookies; diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/RemoteEJBContext.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/RemoteEJBContext.java index f3801433bb0..a7608cc3dcb 100644 --- a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/RemoteEJBContext.java +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/http/client/RemoteEJBContext.java @@ -149,7 +149,7 @@ public Object lookup(String name) throws NamingException { // After we have obtained the class name of the remote interface, generate // a proxy based on it. - return EjbRestProxyFactory.newProxy( + return EjbHttpProxyFactory.newProxy( Class.forName(className), clientBuilder.build() .target(remotePayaraURI) From 002bd86753a33a59dc27c09f806f19473a5335b3 Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Thu, 14 Mar 2019 12:30:12 +0000 Subject: [PATCH 029/108] fixed refactor imports --- .../ejb/rest/client/RemoteEJBContext.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java index 22c733c1a5d..30d2c2aebcf 100644 --- a/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java +++ b/appserver/ejb/ejb-http-remoting/client/src/main/java/fish/payara/ejb/rest/client/RemoteEJBContext.java @@ -39,15 +39,15 @@ */ package fish.payara.ejb.rest.client; -import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_CONNECT_TIMEOUT; -import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_EXECUTOR_SERVICE; -import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_HOSTNAME_VERIFIER; -import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_KEY_STORE; -import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_READ_TIMEOUT; -import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE; -import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_SSL_CONTEXT; -import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_TRUST_STORE; -import static fish.payara.ejb.http.client.RemoteEJBContextFactory.FISH_PAYARA_WITH_CONFIG; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_CONNECT_TIMEOUT; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_EXECUTOR_SERVICE; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_HOSTNAME_VERIFIER; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_KEY_STORE; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_READ_TIMEOUT; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_SCHEDULED_EXECUTOR_SERVICE; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_SSL_CONTEXT; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_TRUST_STORE; +import static fish.payara.ejb.rest.client.RemoteEJBContextFactory.FISH_PAYARA_WITH_CONFIG; import static java.util.concurrent.TimeUnit.MICROSECONDS; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; From 69ebae68bc2028ddbac89ce8c7f32c0dc5575cc2 Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Thu, 14 Mar 2019 14:40:06 +0000 Subject: [PATCH 030/108] minor changes and unused package removal --- .../main/java/fish/payara/micro/impl/PayaraMicroImpl.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java b/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java index 497da75af72..a2e88bdc9e0 100644 --- a/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java +++ b/appserver/extras/payara-micro/payara-micro-core/src/main/java/fish/payara/micro/impl/PayaraMicroImpl.java @@ -91,7 +91,6 @@ import java.io.FileNotFoundException; import java.io.OutputStream; import java.util.Arrays; -import java.util.HashMap; import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.logging.Formatter; @@ -1548,7 +1547,7 @@ private void deployAll() throws GlassFishException { if (deployments != null) { for (File war : deployments) { - boolean hasDefinedContextRoot = (contextRoot != null && contextRoot.isEmpty() == false); + boolean hasDefinedContextRoot = (contextRoot != null && !contextRoot.isEmpty()); if (war.exists() && war.canRead()) { String deployContext = war.getName().substring(0, war.getName().length() - 4); @@ -1586,7 +1585,7 @@ private void deployAll() throws GlassFishException { for (File entry : deploymentDirEntries) { - boolean hasDefinedContextRoot = (contextRoot != null && contextRoot.isEmpty() == false); + boolean hasDefinedContextRoot = (contextRoot != null && !contextRoot.isEmpty()); String entryPath = entry.getAbsolutePath(); if (entry.isFile() && entry.canRead() && (entryPath.endsWith(".war") || entryPath.endsWith(".ear") || entryPath.endsWith(".jar") || entryPath.endsWith(".rar"))) { From 0235f2fc1385946728cdcbea3685ee400795b7c0 Mon Sep 17 00:00:00 2001 From: Andrew Pielage Date: Thu, 14 Mar 2019 15:26:48 +0000 Subject: [PATCH 031/108] Revert "QA-3 Sonar PR analysis" --- Jenkinsfile | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index f10bbd2139d..ce9625ff46f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -27,25 +27,11 @@ pipeline { stage('Build') { steps { echo '*#*#*#*#*#*#*#*#*#*#*#*# Building SRC *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#' - script{ - env.GIT_COMMIT = sh 'git rev-parse HEAD' - } - withCredentials([string(credentialsId: 'jenkins-held-sonarcloud-token-secret', variable: 'sonarToken')]) { - sh """mvn -B -V -ff -e clean install -PQuickBuild \ - -Djavax.net.ssl.trustStore=${env.JAVA_HOME}/jre/lib/security/cacerts \ - -Djavax.xml.accessExternalSchema=all -Dbuild.number=${payaraBuildNumber} \ - -Dsurefire.rerunFailingTestsCount=2 \ - -Dsonar.pullrequest.base=${env.ghprbTargetBranch} \ - -Dsonar.pullrequest.branch=${env.ghprbPullAuthorLogin}/${env.ghprbSourceBranch} \ - -Dsonar.pullrequest.key=${env.ghprbPullId} \ - -Dsonar.pullrequest.provider=GitHub \ - -Dsonar.pullrequest.github.repository=payara/payara \ - -Dsonar.organization=payara \ - -Dsonar.host.url=https://sonarcloud.io \ - -Dsonar.login=${sonarToken} \ - sonar:sonar""" - } - echo '*#*#*#*#*#*#*#*#*#*#*#*# Built SRC *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#' + sh """mvn -B -V -ff -e clean install -PQuickBuild \ + -Djavax.net.ssl.trustStore=${env.JAVA_HOME}/jre/lib/security/cacerts \ + -Djavax.xml.accessExternalSchema=all -Dbuild.number=${payaraBuildNumber} \ + -Dsurefire.rerunFailingTestsCount=2""" + echo '*#*#*#*#*#*#*#*#*#*#*#*# Built SRC *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#' } post{ success{ From 95fe53460293c3c1d63abd92cd569b1897efb9b8 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Fri, 15 Mar 2019 09:49:53 +0100 Subject: [PATCH 032/108] PAYARA-3466 moved all JSON output tweaks to mixin interface --- .../openapi/impl/model/ExtensibleImpl.java | 4 +-- .../openapi/impl/model/ExtensibleTreeMap.java | 3 -- .../openapi/impl/model/PathItemImpl.java | 3 -- .../impl/model/servers/ServerImpl.java | 5 ---- .../app/provider/mixin/ExtensionsMixin.java | 30 +++++++++++++++---- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index e655d759b7b..c549ef80659 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -51,17 +51,15 @@ import org.eclipse.microprofile.openapi.annotations.extensions.Extension; import org.eclipse.microprofile.openapi.models.Extensible; -import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; public abstract class ExtensibleImpl> implements Extensible { private static final Logger LOGGER = Logger.getLogger(ExtensibleImpl.class.getName()); - + protected Map extensions = new LinkedHashMap<>(); - @JsonAnyGetter @Override public Map getExtensions() { return extensions; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java index 67c8f1318c4..8ed4c5ea37c 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java @@ -6,8 +6,6 @@ import org.eclipse.microprofile.openapi.models.Extensible; -import com.fasterxml.jackson.annotation.JsonAnyGetter; - public abstract class ExtensibleTreeMap> extends TreeMap implements Extensible { @@ -21,7 +19,6 @@ protected ExtensibleTreeMap(Map items) { super(items); } - @JsonAnyGetter @Override public final Map getExtensions() { return extensions; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java index a3fa982fe03..48dcdc3e19d 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/PathItemImpl.java @@ -50,8 +50,6 @@ import org.eclipse.microprofile.openapi.models.parameters.Parameter; import org.eclipse.microprofile.openapi.models.servers.Server; -import com.fasterxml.jackson.annotation.JsonIgnore; - public class PathItemImpl extends ExtensibleImpl implements PathItem { protected String ref; @@ -178,7 +176,6 @@ public void setTRACE(Operation trace) { this.trace = trace; } - @JsonIgnore @Override public Map getOperations() { return readOperationsMap(); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java index 566764f8c8a..b3dc2e1b159 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java @@ -48,9 +48,6 @@ import org.eclipse.microprofile.openapi.models.servers.ServerVariable; import org.eclipse.microprofile.openapi.models.servers.ServerVariables; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; public class ServerImpl extends ExtensibleImpl implements Server { @@ -86,13 +83,11 @@ public ServerVariables getVariables() { : new ServerVariablesImpl(variables); } - @JsonIgnore @Override public void setVariables(ServerVariables variables) { this.variables = variables; } - @JsonProperty("variables") @Override public void setVariables(Map variables) { this.variables = variables; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/rest/app/provider/mixin/ExtensionsMixin.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/rest/app/provider/mixin/ExtensionsMixin.java index 1189a77de0e..b063c4a02cd 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/rest/app/provider/mixin/ExtensionsMixin.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/rest/app/provider/mixin/ExtensionsMixin.java @@ -40,33 +40,51 @@ package fish.payara.microprofile.openapi.impl.rest.app.provider.mixin; import java.util.List; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import org.eclipse.microprofile.openapi.models.Operation; import org.eclipse.microprofile.openapi.models.Paths; +import org.eclipse.microprofile.openapi.models.PathItem.HttpMethod; import org.eclipse.microprofile.openapi.models.security.SecurityRequirement; +import org.eclipse.microprofile.openapi.models.servers.ServerVariable; +import org.eclipse.microprofile.openapi.models.servers.ServerVariables; public interface ExtensionsMixin { @JsonProperty("enum") - public abstract void getEnumeration(); + void getEnumeration(); @JsonProperty("default") - public abstract void getDefaultValue(); + void getDefaultValue(); @JsonProperty("$ref") - public abstract void getRef(); + void getRef(); @JsonIgnore - public abstract void setAdditionalProperties(Boolean additionalProperties); + void setAdditionalProperties(Boolean additionalProperties); @JsonInclude(Include.NON_EMPTY) - public abstract List getSecurity(); + List getSecurity(); @JsonInclude(Include.ALWAYS) - public abstract Paths getPaths(); + Paths getPaths(); + + @JsonAnyGetter + Map getExtensions(); + + @JsonIgnore + Map getOperations(); + + @JsonIgnore + void setVariables(ServerVariables variables); + + @JsonProperty("variables") + void setVariables(Map variables); } \ No newline at end of file From cbd67d43439c8b5ae665534a2ffb11b5bc5219f1 Mon Sep 17 00:00:00 2001 From: arjantijms Date: Fri, 15 Mar 2019 16:04:51 +0000 Subject: [PATCH 033/108] PAYARA-3684 Security Cleaning sweep 5 Mostly factored out functionality from Realm --- .../security/auth/login/LDAPLoginModule.java | 3 +- .../auth/login/common/PasswordCredential.java | 9 +- .../security/auth/login/package-info.java | 53 ++ .../security/auth/realm/AbstractRealm.java | 170 +++++ .../security/auth/realm/BaseRealm.java | 276 +++++++ .../security/auth/realm/GroupMapper.java | 26 +- .../auth/realm/GroupNotEmptyException.java | 4 +- .../auth/realm/InvalidOperationException.java | 4 +- .../auth/realm/NoSuchUserException.java | 4 +- .../enterprise/security/auth/realm/Realm.java | 702 +++++------------- .../security/auth/realm/RealmConfig.java | 24 +- .../auth/realm/RealmsManagerStore.java | 88 +++ .../enterprise/security/auth/realm/User.java | 3 +- .../realm/certificate/CertificateRealm.java | 60 +- .../security/auth/realm/file/FileRealm.java | 8 +- .../auth/realm/file/FileRealmUser.java | 12 +- .../security/auth/realm/ldap/LDAPRealm.java | 152 ++-- .../security/auth/realm/package-info.java | 54 ++ 18 files changed, 972 insertions(+), 680 deletions(-) create mode 100644 nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/package-info.java create mode 100644 nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AbstractRealm.java create mode 100644 nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseRealm.java create mode 100644 nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmsManagerStore.java create mode 100644 nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/package-info.java diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LDAPLoginModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LDAPLoginModule.java index 35589c17a53..41239720375 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LDAPLoginModule.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LDAPLoginModule.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.login; import static com.sun.enterprise.security.auth.realm.ldap.LDAPRealm.MODE_FIND_BIND; @@ -73,7 +73,6 @@ * are taken as group names in which the user has membership. If no entries are found, the group membership is empty. * * - * */ public class LDAPLoginModule extends BasePasswordLoginModule { diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/PasswordCredential.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/PasswordCredential.java index f8547b61dee..9f151d94fa0 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/PasswordCredential.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/PasswordCredential.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.login.common; import java.util.Arrays; @@ -46,13 +46,12 @@ * This class holds the user password for the shared password realm and the realm name. This credential is added as a * private credential to the JAAS subject. */ - public class PasswordCredential { private String username; private char[] password; private String realm; private boolean readOnly = false; - + // target_name is filled in by the SecSecurityServer interceptor // only when a CSIv2 GSSUP authenticator is received. private byte[] target_name = {}; @@ -74,11 +73,11 @@ public PasswordCredential(String user, char[] password, String realm) { if (this.username == null) { this.username = ""; } - + if (this.password == null) { this.password = new char[] {}; } - + if (this.realm == null) { this.realm = ""; } diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/package-info.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/package-info.java new file mode 100644 index 00000000000..797c9e60745 --- /dev/null +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/package-info.java @@ -0,0 +1,53 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. + * All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the + * "Classpath" exception as provided by the Payara Foundation in the GPL + * Version 2 section of the License file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +/** + * This package contains the LoginModules uses by Payara for its native identity stores. + * + *

+ * LoginModules in Payara have to be paired with Realms, which are in the + * com.sun.enterprise.security.auth.realm package. + * + *

+ * A LoginModule is the facade to a realm that only exposes credential validation. + * + */ +package com.sun.enterprise.security.auth.login; \ No newline at end of file diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AbstractRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AbstractRealm.java new file mode 100644 index 00000000000..e7d11aa64d7 --- /dev/null +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AbstractRealm.java @@ -0,0 +1,170 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates +package com.sun.enterprise.security.auth.realm; + +import java.util.Enumeration; + +import com.sun.enterprise.security.util.IASSecurityException; + +/** + * This class contains all abstract methods of a Payara Realm. + * + * @see Realm + * + * @author Arjan Tijms + */ +public abstract class AbstractRealm { + + // ---[ General methods ]------------------------------------------------ + + /** + * Returns a short (preferably less than fifteen characters) description of the kind of + * authentication which is supported by this realm. + * + * @return description of the kind of authentication that is directly supported by this realm. + */ + public abstract String getAuthType(); + + /** + * Returns names of all the users in this particular realm. + * + * @return enumeration of user names (strings) + * @exception BadRealmException if realm data structures are bad + */ + public abstract Enumeration getUserNames() throws BadRealmException; + + /** + * Returns the information recorded about a particular named user. + * + * @param name name of the user whose information is desired + * + * @return the user object + * @exception NoSuchUserException if the user doesn't exist + * @exception BadRealmException if realm data structures are bad + */ + public abstract User getUser(String name) throws NoSuchUserException, BadRealmException; + + /** + * Returns names of all the groups in this particular realm. + * + * @return enumeration of group names (strings) + * @exception BadRealmException if realm data structures are bad + */ + public abstract Enumeration getGroupNames() throws BadRealmException; + + /** + * Returns the name of all the groups that this user belongs to + * + * @param username name of the user in this realm whose group listing is needed. + * + * @return enumeration of group names (strings) + * @exception InvalidOperationException thrown if the realm does not support this operation - e.g. + * Certificate realm does not support this operation + * @throws NoSuchUserException + */ + public abstract Enumeration getGroupNames(String username) throws InvalidOperationException, NoSuchUserException; + + + + // ---[ User management methods ]------------------------------------------------ + + + /** + * @return true if the realm implementation support User Management (add, update, remove user) + */ + public abstract boolean supportsUserManagement(); + + /** + * Adds new user to file realm. User cannot exist already. + * + * @param name User name. + * @param password Cleartext password for the user. + * @param groupList List of groups to which user belongs. + * + * @throws BadRealmException If there are problems adding user. + * @throws IASSecurityException + * + */ + public abstract void addUser(String name, char[] password, String[] groupList) throws BadRealmException, IASSecurityException; + + /** + * Update data for an existing user. User must exist. + * + * @param name Current name of the user to update. + * @param newName New name to give this user. It can be the same as the original name. Otherwise it + * must be a new user name which does not already exist as a user. + * @param password Cleartext password for the user. If non-null the user password is changed to this + * value. If null, the original password is retained. + * @param groups Array of groups to which user belongs. + * + * @throws BadRealmException If there are problems adding user. + * @throws NoSuchUserException If user does not exist. + * @throws IASSecurityException + * + */ + public abstract void updateUser(String name, String newName, char[] password, String[] groups) throws NoSuchUserException, BadRealmException, IASSecurityException; + + /** + * Remove user from file realm. User must exist. + * + * @param name User name. + * + * @throws NoSuchUserException If user does not exist. + * @throws BadRealmException + * + */ + public abstract void removeUser(String name) throws NoSuchUserException, BadRealmException; + + /** + * Persist the realm data to permanent storage + * + * @throws com.sun.enterprise.security.auth.realm.BadRealmException + */ + public abstract void persist() throws BadRealmException; + + /** + * Refreshes the realm data so that new users/groups are visible. + * + * @exception BadRealmException if realm data structures are bad + */ + public abstract void refresh() throws BadRealmException; + +} diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseRealm.java new file mode 100644 index 00000000000..bab835598e7 --- /dev/null +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseRealm.java @@ -0,0 +1,276 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates +package com.sun.enterprise.security.auth.realm; + +import static com.sun.enterprise.security.BaseRealm.JAAS_CONTEXT_PARAM; +import static com.sun.enterprise.security.auth.realm.RealmsManagerStore._getRealmsManager; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +/** + * This class is the base for all Payara Realm classes, and contains common + * object state such as the realm name, general properties and the assign groups. + * + * @author Arjan Tijms + * + */ +public abstract class BaseRealm extends AbstractRealm implements Comparable { + + public static final String PARAM_GROUP_MAPPING = "group-mapping"; + + // For assign-groups + + private static final String PARAM_GROUPS = "assign-groups"; + private static final String GROUPS_SEP = ","; + private static final String DEFAULT_DEF_DIG_ALGO_VAL = "SHA-256"; + + // All realms have a set of properties from config file, consolidate. + + private String realmName; + private Properties contextProperties; + private List assignGroups; + private String defaultDigestAlgorithm; + + protected GroupMapper groupMapper; + + // ---[ Instance methods ]------------------------------------------------ + + /** + * The default the constructor creates a realm which will later be initialized, + * either from properties or by deserializing. + */ + protected BaseRealm() { + contextProperties = new Properties(); + } + + /** + * Initialize a realm with some properties. This can be used when instantiating realms from their + * descriptions. This method may only be called a single time. + * + * @param properties initialization parameters used by this realm. + * @exception BadRealmException if the configuration parameters identify a corrupt realm + * @exception NoSuchRealmException if the configuration parameters specify a realm which doesn't + * exist + */ + protected void init(Properties properties) throws BadRealmException, NoSuchRealmException { + String groupList = properties.getProperty(PARAM_GROUPS); + + if (groupList != null && groupList.length() > 0) { + setProperty(PARAM_GROUPS, groupList); + + assignGroups = new ArrayList(); + for (String group : groupList.split(GROUPS_SEP)) { + if (!assignGroups.contains(group)) { + assignGroups.add(group); + } + } + } + + String groupMapping = properties.getProperty(PARAM_GROUP_MAPPING); + if (groupMapping != null) { + groupMapper = new GroupMapper(); + groupMapper.parse(groupMapping); + } + + String defaultDigestAlgo = null; + if (_getRealmsManager() != null) { + defaultDigestAlgo = _getRealmsManager().getDefaultDigestAlgorithm(); + } + + defaultDigestAlgorithm = defaultDigestAlgo == null ? DEFAULT_DEF_DIG_ALGO_VAL : defaultDigestAlgo; + } + + /** + * Add assign groups to given array of groups. To be used by getGroupNames. + * + * @param groups + * @return + */ + protected String[] addAssignGroups(String[] groups) { + String[] resultGroups = groups; + + if (assignGroups != null && assignGroups.size() > 0) { + List groupList = new ArrayList<>(); + if (groups != null && groups.length > 0) { + for (String group : groups) { + groupList.add(group); + } + } + + for (String assignGroup : assignGroups) { + if (!groupList.contains(assignGroup)) { + groupList.add(assignGroup); + } + } + resultGroups = groupList.toArray(new String[groupList.size()]); + } + + return resultGroups; + } + + protected ArrayList getMappedGroupNames(String group) { + if (groupMapper == null) { + return null; + } + + ArrayList result = new ArrayList(); + groupMapper.getMappedGroups(group, result); + + return result; + } + + /** + * Refreshes the realm data so that new users/groups are visible. + * + * @param configName + * @exception BadRealmException if realm data structures are bad + */ + public void refresh(String configName) throws BadRealmException { + // do nothing + } + + /** + * Returns the name of this realm. + * + * @return realm name. + */ + public final String getName() { + return realmName; + } + + /** + * Assigns the name of this realm, and stores it in the cache of realms. Used when initializing a + * newly created in-memory realm object; if the realm already has a name, there is no effect. + * + * @param name name to be assigned to this realm. + */ + protected final void setName(String name) { + if (realmName != null) { + return; + } + + realmName = name; + } + + protected String getDefaultDigestAlgorithm() { + return defaultDigestAlgorithm; + } + + /** + * Get a realm property. + * + * @param name property name. + * @return + * @returns value. + * + */ + public synchronized String getProperty(String name) { + return contextProperties.getProperty(name); + } + + /** + * Set a realm property. + * + * @param name property name. + * @param value property value. + * + */ + public synchronized void setProperty(String name, String value) { + contextProperties.setProperty(name, value); + } + + /** + * Return properties of the realm. + * + * @return + */ + protected synchronized Properties getProperties() { + return contextProperties; + } + + /** + * Returns name of JAAS context used by this realm. + * + *

+ * The JAAS context is defined in server.xml auth-realm element associated with this realm. + * + * @return String containing JAAS context name. + * + */ + public synchronized String getJAASContext() { + return contextProperties.getProperty(JAAS_CONTEXT_PARAM); + } + + /** + * Returns the name of this realm. + * + * @return name of realm. + */ + @Override + public String toString() { + return realmName; + } + + /** + * Compares a realm to another. + * + *

+ * The comparison first considers the authentication type, so that realms supporting the same + * kind of user authentication are grouped together. + * Then it compares realm realm names. Realms compare "before" other kinds of objects + * (i.e. there's only a partial order defined, in the case that those other objects compare themselves + * "before" a realm object). + */ + @Override + public int compareTo(Realm otherRealm) { + String str = otherRealm.getAuthType(); + int temp; + + if ((temp = getAuthType().compareTo(str)) != 0) { + return temp; + } + + return getName().compareTo(otherRealm.getName()); + } + +} diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupMapper.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupMapper.java index f9b5d16cda4..4c35734e66c 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupMapper.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupMapper.java @@ -37,10 +37,14 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; /** * @@ -64,9 +68,7 @@ public void parse(String mappingStr) { validate(mappedGroup, mappingGroups); for (String grp : mappingGroups) { int aIndex = grp.indexOf("->"); - String theGroup = (aIndex > 0) - ? grp.substring(0, aIndex).trim() - : grp.trim(); + String theGroup = (aIndex > 0) ? grp.substring(0, aIndex).trim() : grp.trim(); List mappedGroupList = groupMappingTable.get(theGroup); if (mappedGroupList == null) { mappedGroupList = new ArrayList<>(); @@ -81,16 +83,20 @@ public void getMappedGroups(String group, List result) { if (result == null) { throw new RuntimeException("result argument cannot be NULL"); } + List mappedGrps = groupMappingTable.get(group); if (mappedGrps == null || mappedGrps.isEmpty()) { return; } + addUnique(result, mappedGrps); - // look for transitive closure + + // Look for transitive closure List result1 = new ArrayList<>(); for (String str : mappedGrps) { getMappedGroups(group, str, result1); } + addUnique(result, result1); } @@ -103,15 +109,17 @@ private void addUnique(List dest, List src) { } private void getMappedGroups(String group, String str, List result) { - List mappedGrps = groupMappingTable.get(str); if (mappedGrps == null || mappedGrps.isEmpty()) { return; } + if (mappedGrps.contains(group)) { throw new RuntimeException("Illegal Mapping: cycle detected with group'" + group); } + addUnique(result, mappedGrps); + for (String str1 : mappedGrps) { getMappedGroups(group, str1, result); } @@ -120,9 +128,7 @@ private void getMappedGroups(String group, String str, List result) { private void validate(String mappedGroup, String[] mappingGroups) { for (String str : mappingGroups) { int aIndex = str.indexOf("->"); - String theGroup = (aIndex > 0) - ? str.substring(0, aIndex) - : str; + String theGroup = (aIndex > 0) ? str.substring(0, aIndex) : str; if (theGroup.equals(mappedGroup)) { throw new RuntimeException("Illegal Mapping: Identity Mapping of group '" + theGroup + "' to '" + theGroup + "'"); } diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupNotEmptyException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupNotEmptyException.java index 07702d020d9..41607f13e10 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupNotEmptyException.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupNotEmptyException.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ - +// Portions Copyright [2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm; /** @@ -46,7 +46,7 @@ * @author Harpreet Singh */ public class GroupNotEmptyException extends Exception { - + private static final long serialVersionUID = 873043596300984484L; /** diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/InvalidOperationException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/InvalidOperationException.java index 5adbeaedc00..9c9cfe09b8c 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/InvalidOperationException.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/InvalidOperationException.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm; /** @@ -47,7 +47,7 @@ * @author Harpreet Singh */ public class InvalidOperationException extends Exception { - + private static final long serialVersionUID = 1124276549235903088L; /** diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchUserException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchUserException.java index 01185d4dac1..d2e6256ba76 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchUserException.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchUserException.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm; /** @@ -46,7 +46,7 @@ * @author Harish Prabandham */ public class NoSuchUserException extends Exception { - + private static final long serialVersionUID = -4061500111336089813L; /** diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java index 4f33f13c688..9625e384aa1 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java @@ -37,20 +37,20 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.security.auth.realm; -import static com.sun.enterprise.security.BaseRealm.JAAS_CONTEXT_PARAM; +import static com.sun.enterprise.security.SecurityLoggerInfo.realmCreated; +import static com.sun.enterprise.security.SecurityLoggerInfo.realmDeleted; +import static com.sun.enterprise.security.SecurityLoggerInfo.realmUpdated; +import static com.sun.enterprise.security.auth.realm.RealmsManagerStore.getRealmsManager; +import static com.sun.enterprise.security.auth.realm.RealmsManagerStore.tryGetRealmsManager; import static java.util.logging.Level.FINER; +import static java.util.logging.Level.INFO; import static org.glassfish.external.probe.provider.PluginPoint.SERVER; -import java.lang.ref.WeakReference; -import java.util.ArrayList; import java.util.Enumeration; -import java.util.List; import java.util.Properties; -import java.util.StringTokenizer; -import java.util.logging.Level; import java.util.logging.Logger; import org.glassfish.external.probe.provider.StatsProviderManager; @@ -60,108 +60,42 @@ import org.jvnet.hk2.annotations.Contract; import com.sun.enterprise.security.SecurityLoggerInfo; -import com.sun.enterprise.security.util.IASSecurityException; import com.sun.enterprise.util.LocalStringManagerImpl; /** * - * @see java.security.Principal + * * @author Harish Prabandham * @author Harpreet Singh * @author Jyri Virkki * @author Shing Wai Chan * + * @see java.security.Principal */ @Contract -public abstract class Realm implements Comparable { +public abstract class Realm extends BaseRealm implements Comparable { protected static final Logger _logger = SecurityLoggerInfo.getLogger(); - - public static final String PARAM_GROUP_MAPPING = "group-mapping"; - private static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(Realm.class); - private static WeakReference realmsManager = new WeakReference(null); + private static RealmStatsProvider realmStatsProvier; - // For assign-groups - private static final String PARAM_GROUPS = "assign-groups"; - private static final String GROUPS_SEP = ","; - private static final String DEFAULT_DEF_DIG_ALGO_VAL = "SHA-256"; - // Keep a mapping from "default" to default realm (if no such named // realm is present) for the sake of all the hardcoded accesses to it. // This needs to be removed as part of RI security service cleanup. public static final String RI_DEFAULT = "default"; + - private String myName; - - // All realms have a set of properties from config file, consolidate. - private Properties ctxProps; - private List assignGroups; - protected GroupMapper groupMapper; - private String defaultDigestAlgorithm; - - /** - * Returns the name of this realm. - * - * @return realm name. - */ - public final String getName() { - return myName; - } - - protected String getDefaultDigestAlgorithm() { - return defaultDigestAlgorithm; - } - - /** - * Assigns the name of this realm, and stores it in the cache of realms. Used when initializing a - * newly created in-memory realm object; if the realm already has a name, there is no effect. - * - * @param name name to be assigned to this realm. - */ - protected final void setName(String name) { - if (myName != null) { - return; - } - myName = name; - } - + // ---[ Public Static methods ]------------------------------------------------ + + /** - * Returns the name of this realm. - * - * @return name of realm. - */ - @Override - public String toString() { - return myName; - } - - /** - * Compares a realm to another. The comparison first considers the authentication type, so that - * realms supporting the same kind of user authentication are grouped together. Then it compares - * realm realm names. Realms compare "before" other kinds of objects (i.e. there's only a partial - * order defined, in the case that those other objects compare themselves "before" a realm object). - */ - @Override - public int compareTo(Realm otherRealm) { - String str = otherRealm.getAuthType(); - int temp; - - if ((temp = getAuthType().compareTo(str)) != 0) { - return temp; - } - - return getName().compareTo(otherRealm.getName()); - } - - /** - * Instantiate a Realm with the given name and properties using the Class name given. This method is - * used by iAS and not RI. + * Instantiate a Realm with the given name and properties using the Class name given. * * @param name Name of the new realm. * @param className Java Class name of the realm to create. * @param props Properties containing values of the Property element from server.xml + * * @returns Reference to the new Realm. The Realm class keeps an internal list of all instantiated * realms. * @throws BadRealmException If the requested realm cannot be instantiated. @@ -181,13 +115,13 @@ public static synchronized Realm instantiate(String name, String className, Prop } /** - * Instantiate a Realm with the given name and properties using the Class name given. This method is - * used by iAS and not RI. + * Instantiate a Realm with the given name and properties using the Class name given. * * @param name Name of the new realm. * @param className Java Class name of the realm to create. * @param props Properties containing values of the Property element from server.xml * @param configName the config to which this realm belongs + * * @returns Reference to the new Realm. The Realm class keeps an internal list of all instantiated * realms. * @throws BadRealmException If the requested realm cannot be instantiated. @@ -204,119 +138,8 @@ public static synchronized Realm instantiate(String name, String className, Prop } return realmClass; - } - - private static void registerRealmStatsProvier() { - if (realmStatsProvier == null) { - getRealmStatsProvier(); - StatsProviderManager.register("security", SERVER, "security/realm", realmStatsProvier); - } - } - - public static synchronized void getRealmStatsProvier() { - if (realmStatsProvier == null) { - realmStatsProvier = new RealmStatsProvider(); - } - } - - /** - * Instantiates a Realm class of the given type and invokes its init() - * - */ - private static synchronized Realm doInstantiate(String name, String className, Properties props) throws BadRealmException { - - ServiceLocator serviceLocator = Globals.getDefaultHabitat(); - try { - RealmsManager realmsManager = getRealmsManager(); - - // Try a HK2 route first - Realm realm = serviceLocator.getService(Realm.class, name); - if (realm == null) { - try { - // TODO: workaround here. Once fixed in V3 we should be able to use - // Context ClassLoader instead. - realm = (Realm) serviceLocator.getService(ClassLoaderHierarchy.class) - .getCommonClassLoader() - .loadClass(className) - .newInstance(); - } catch (ClassNotFoundException ex) { - realm = (Realm) Class.forName(className).newInstance(); - } - } - - realm.setName(name); - realm.init(props); - if (realmsManager == null) { - throw new BadRealmException("Unable to locate RealmsManager Service"); - } - _logger.log(FINER, SecurityLoggerInfo.realmCreated, new Object[] { name, className }); - return realm; - - } catch (NoSuchRealmException | InstantiationException | IllegalAccessException | ClassNotFoundException ex) { - throw new BadRealmException(ex); - } - } - - /** - * Replace a Realm instance. Can be used by a Realm subclass to replace a previously initialized - * instance of itself. Future getInstance requests will then obtain the new instance. - * - *

- * Minimal error checking is done. The realm being replaced must already exist (instantiate() was - * previously called), the new instance must be fully initialized properly and it must of course be - * of the same class as the previous instance. - * - * @param realm The new realm instance. - * @param name The (previously instantiated) name for this realm. - * - */ - protected static synchronized void updateInstance(Realm realm, String name) { - RealmsManager realmsManager = getRealmsManager(); - if (realmsManager == null) { - throw new RuntimeException("Unable to locate RealmsManager Service"); - } - - Realm oldRealm = realmsManager.getFromLoadedRealms(name); - if (!oldRealm.getClass().equals(realm.getClass())) { - // would never happen unless bug in realm subclass - throw new Error("Incompatible class " + realm.getClass() + " in replacement realm " + name); - } - realm.setName(oldRealm.getName()); - realmsManager.putIntoLoadedRealms(name, realm); - _logger.log(FINER, SecurityLoggerInfo.realmUpdated, new Object[] { realm.getName() }); - } - - /** - * Replace a Realm instance. Can be used by a Realm subclass to replace a previously initialized - * instance of itself. Future getInstance requests will then obtain the new instance. - * - *

- * Minimal error checking is done. The realm being replaced must already exist (instantiate() was - * previously called), the new instance must be fully initialized properly and it must of course be - * of the same class as the previous instance. - * - * @param configName - * @param realm The new realm instance. - * @param name The (previously instantiated) name for this realm. - * - */ - protected static synchronized void updateInstance(String configName, Realm realm, String name) { - RealmsManager realmsManager = getRealmsManager(); - if (realmsManager == null) { - throw new RuntimeException("Unable to locate RealmsManager Service"); - } - - Realm oldRealm = realmsManager.getFromLoadedRealms(configName, name); - if (!oldRealm.getClass().equals(realm.getClass())) { - // would never happen unless bug in realm subclass - throw new Error("Incompatible class " + realm.getClass() + " in replacement realm " + name); - } - realm.setName(oldRealm.getName()); - realmsManager.putIntoLoadedRealms(configName, name, realm); - _logger.log(FINER, SecurityLoggerInfo.realmUpdated, new Object[] { realm.getName() }); - } - + /** * Convenience method which returns the Realm object representing the current default realm. * Equivalent to getInstance(getDefaultRealm()). @@ -335,12 +158,7 @@ public static synchronized Realm getDefaultInstance() throws NoSuchRealmExceptio * */ public static synchronized String getDefaultRealm() { - RealmsManager realmsManager = getRealmsManager(); - if (realmsManager == null) { - throw new RuntimeException("Unable to locate RealmsManager Service"); - } - - return realmsManager.getDefaultRealmName(); + return tryGetRealmsManager().getDefaultRealmName(); } /** @@ -350,115 +168,29 @@ public static synchronized String getDefaultRealm() { * */ public static synchronized void setDefaultRealm(String realmName) { - RealmsManager realmsManager = getRealmsManager(); - if (realmsManager == null) { - throw new RuntimeException("Unable to locate RealmsManager Service"); - } - - realmsManager.setDefaultRealmName(realmName); - } - - /** - * Remove realm with given name from cache. - * - * @param realmName - * @exception NoSuchRealmException - */ - public static synchronized void unloadInstance(String realmName) throws NoSuchRealmException { - // make sure instance exist - getInstance(realmName); - RealmsManager mgr = getRealmsManager(); - if (mgr != null) { - mgr.removeFromLoadedRealms(realmName); - } else { - throw new RuntimeException("Unable to locate RealmsManager Service"); - } - _logger.log(Level.INFO, SecurityLoggerInfo.realmDeleted, realmName); - } - - /** - * Remove realm with given name from cache. - * - * @param configName - * @param realmName - * @exception NoSuchRealmException - */ - public static synchronized void unloadInstance(String configName, String realmName) throws NoSuchRealmException { - // make sure instance exist - // getInstance(configName, realmName); - RealmsManager mgr = getRealmsManager(); - if (mgr != null) { - mgr.removeFromLoadedRealms(configName, realmName); - } else { - throw new RuntimeException("Unable to locate RealmsManager Service"); - } - _logger.log(Level.INFO, SecurityLoggerInfo.realmDeleted, realmName); - } - - /** - * Set a realm property. - * - * @param name property name. - * @param value property value. - * - */ - public synchronized void setProperty(String name, String value) { - ctxProps.setProperty(name, value); - } - - /** - * Get a realm property. - * - * @param name property name. - * @return - * @returns value. - * - */ - public synchronized String getProperty(String name) { - return ctxProps.getProperty(name); + tryGetRealmsManager().setDefaultRealmName(realmName); } - - /** - * Return properties of the realm. - * - * @return - */ - protected synchronized Properties getProperties() { - return ctxProps; - } - - /** - * Returns name of JAAS context used by this realm. - * - *

- * The JAAS context is defined in server.xml auth-realm element associated with this realm. - * - * @return String containing JAAS context name. - * - */ - public synchronized String getJAASContext() { - return ctxProps.getProperty(JAAS_CONTEXT_PARAM); - } - + /** * Returns the realm identified by the name which is passed as a parameter. This function knows * about all the realms which exist; it is not possible to store (or create) one which is not * accessible through this routine. * * @param name identifies the realm + * * @return the requested realm * @exception NoSuchRealmException if the realm is invalid * @exception BadRealmException if realm data structures are bad */ public static synchronized Realm getInstance(String name) throws NoSuchRealmException { - Realm retval = _getInstance(name); + Realm realmInstance = _getInstance(name); - if (retval == null) { + if (realmInstance == null) { throw new NoSuchRealmException( - localStrings.getLocalString("realm.no_such_realm", name + " realm does not exist.", new Object[] { name })); + localStrings.getLocalString("realm.no_such_realm", name + " realm does not exist.", new Object[] { name })); } - return retval; + return realmInstance; } /** @@ -468,126 +200,31 @@ public static synchronized Realm getInstance(String name) throws NoSuchRealmExce * * @param configName * @param name identifies the realm + * * @return the requested realm * @exception NoSuchRealmException if the realm is invalid * @exception BadRealmException if realm data structures are bad */ public static synchronized Realm getInstance(String configName, String name) throws NoSuchRealmException { - Realm retval = _getInstance(configName, name); + Realm realmInstance = _getInstance(configName, name); - if (retval == null) { + if (realmInstance == null) { throw new NoSuchRealmException( - localStrings.getLocalString("realm.no_such_realm", name + " realm does not exist.", new Object[] { name })); + localStrings.getLocalString("realm.no_such_realm", name + " realm does not exist.", new Object[] { name })); } - return retval; + return realmInstance; } - - /** - * This is a private method for getting realm instance. If realm does not exist, then it will not - * return null rather than throw exception. - * - * @param name identifies the realm - * @return the requested realm - */ - private static synchronized Realm _getInstance(String name) { - RealmsManager mgr = getRealmsManager(); - if (mgr != null) { - return mgr._getInstance(name); - } else { - throw new RuntimeException("Unable to locate RealmsManager Service"); - } - } - - /** - * This is a private method for getting realm instance. If realm does not exist, then it will not - * return null rather than throw exception. - * - * @param name identifies the realm - * @return the requested realm - */ - private static synchronized Realm _getInstance(String configName, String name) { - RealmsManager mgr = getRealmsManager(); - if (mgr != null) { - return mgr._getInstance(configName, name); - } else { - throw new RuntimeException("Unable to locate RealmsManager Service"); - } - } - + /** * Returns the names of accessible realms. * * @return set of realm names */ - public static synchronized Enumeration getRealmNames() { - RealmsManager mgr = getRealmsManager(); - if (mgr != null) { - return mgr.getRealmNames(); - } - throw new RuntimeException("Unable to locate RealmsManager Service"); + public static synchronized Enumeration getRealmNames() { + return tryGetRealmsManager().getRealmNames(); } - - /** - * The default constructor creates a realm which will later be initialized, either from properties - * or by deserializing. - */ - protected Realm() { - ctxProps = new Properties(); - } - - /** - * Initialize a realm with some properties. This can be used when instantiating realms from their - * descriptions. This method may only be called a single time. - * - * @param props initialization parameters used by this realm. - * @exception BadRealmException if the configuration parameters identify a corrupt realm - * @exception NoSuchRealmException if the configuration parameters specify a realm which doesn't - * exist - */ - protected void init(Properties props) throws BadRealmException, NoSuchRealmException { - String groupList = props.getProperty(PARAM_GROUPS); - if (groupList != null && groupList.length() > 0) { - this.setProperty(PARAM_GROUPS, groupList); - assignGroups = new ArrayList(); - StringTokenizer st = new StringTokenizer(groupList, GROUPS_SEP); - while (st.hasMoreTokens()) { - String grp = st.nextToken(); - if (!assignGroups.contains(grp)) { - assignGroups.add(grp); - } - } - } - String groupMapping = props.getProperty(PARAM_GROUP_MAPPING); - if (groupMapping != null) { - groupMapper = new GroupMapper(); - groupMapper.parse(groupMapping); - } - String defaultDigestAlgo = null; - if (_getRealmsManager() != null) { - defaultDigestAlgo = _getRealmsManager().getDefaultDigestAlgorithm(); - } - this.defaultDigestAlgorithm = (defaultDigestAlgo == null) ? DEFAULT_DEF_DIG_ALGO_VAL : defaultDigestAlgo; - } - - private static synchronized RealmsManager _getRealmsManager() { - if (realmsManager.get() == null) { - if (Globals.getDefaultHabitat() != null) { - realmsManager = new WeakReference(Globals.get(RealmsManager.class)); - } else { - return null; - } - } - return realmsManager.get(); - } - - private static RealmsManager getRealmsManager() { - if (realmsManager.get() != null) { - return realmsManager.get(); - } - return _getRealmsManager(); - } - + /** * Checks if the given realm name is loaded/valid. * @@ -595,12 +232,7 @@ private static RealmsManager getRealmsManager() { * @return true if realm present, false otherwise. */ public static boolean isValidRealm(String name) { - RealmsManager mgr = getRealmsManager(); - if (mgr != null) { - return mgr.isValidRealm(name); - } - - throw new RuntimeException("Unable to locate RealmsManager Service"); + return tryGetRealmsManager().isValidRealm(name); } /** @@ -611,160 +243,178 @@ public static boolean isValidRealm(String name) { * @return true if realm present, false otherwise. */ public static boolean isValidRealm(String configName, String name) { - RealmsManager mgr = getRealmsManager(); - if (mgr != null) { - return mgr.isValidRealm(configName, name); - } - - throw new RuntimeException("Unable to locate RealmsManager Service"); + return tryGetRealmsManager().isValidRealm(configName, name); } - /** - * Add assign groups to given array of groups. To be used by getGroupNames. - * - * @param grps - * @return - */ - protected String[] addAssignGroups(String[] grps) { - String[] resultGroups = grps; - if (assignGroups != null && assignGroups.size() > 0) { - List groupList = new ArrayList(); - if (grps != null && grps.length > 0) { - for (String grp : grps) { - groupList.add(grp); - } - } - - for (String agrp : assignGroups) { - if (!groupList.contains(agrp)) { - groupList.add(agrp); - } - } - resultGroups = groupList.toArray(new String[groupList.size()]); - } - return resultGroups; - } - - protected ArrayList getMappedGroupNames(String group) { - if (groupMapper != null) { - ArrayList result = new ArrayList(); - groupMapper.getMappedGroups(group, result); - return result; + public static synchronized void getRealmStatsProvier() { + if (realmStatsProvier == null) { + realmStatsProvier = new RealmStatsProvider(); } - return null; } - - // ---[ Abstract methods ]------------------------------------------------ - + /** - * Returns a short (preferably less than fifteen characters) description of the kind of - * authentication which is supported by this realm. + * Remove realm with given name from cache. * - * @return description of the kind of authentication that is directly supported by this realm. + * @param realmName + * @exception NoSuchRealmException */ - public abstract String getAuthType(); - + public static synchronized void unloadInstance(String realmName) throws NoSuchRealmException { + // Make sure instance exist + getInstance(realmName); + + tryGetRealmsManager().removeFromLoadedRealms(realmName); + + _logger.log(INFO, realmDeleted, realmName); + } + /** - * Returns names of all the users in this particular realm. + * Remove realm with given name from cache. * - * @return enumeration of user names (strings) - * @exception BadRealmException if realm data structures are bad + * @param configName + * @param realmName + * @exception NoSuchRealmException */ - public abstract Enumeration getUserNames() throws BadRealmException; + public static synchronized void unloadInstance(String configName, String realmName) throws NoSuchRealmException { + tryGetRealmsManager().removeFromLoadedRealms(configName, realmName); - /** - * Returns the information recorded about a particular named user. - * - * @param name name of the user whose information is desired - * @return the user object - * @exception NoSuchUserException if the user doesn't exist - * @exception BadRealmException if realm data structures are bad - */ - public abstract User getUser(String name) throws NoSuchUserException, BadRealmException; + _logger.log(INFO, realmDeleted, realmName); + } + + + // ---[ Protected Static methods ]------------------------------------------------ + /** - * Returns names of all the groups in this particular realm. + * Replace a Realm instance. Can be used by a Realm subclass to replace a previously initialized + * instance of itself. Future getInstance requests will then obtain the new instance. * - * @return enumeration of group names (strings) - * @exception BadRealmException if realm data structures are bad - */ - public abstract Enumeration getGroupNames() throws BadRealmException; - - /** - * Returns the name of all the groups that this user belongs to + *

+ * Minimal error checking is done. The realm being replaced must already exist (instantiate() was + * previously called), the new instance must be fully initialized properly and it must of course be + * of the same class as the previous instance. * - * @param username name of the user in this realm whose group listing is needed. - * @return enumeration of group names (strings) - * @exception InvalidOperationException thrown if the realm does not support this operation - e.g. - * Certificate realm does not support this operation - * @throws NoSuchUserException - */ - public abstract Enumeration getGroupNames(String username) throws InvalidOperationException, NoSuchUserException; - - /** - * Refreshes the realm data so that new users/groups are visible. + * @param realm The new realm instance. + * @param name The (previously instantiated) name for this realm. * - * @exception BadRealmException if realm data structures are bad */ - public abstract void refresh() throws BadRealmException; + protected static synchronized void updateInstance(Realm realm, String name) { + RealmsManager realmsManager = tryGetRealmsManager(); - /** - * Refreshes the realm data so that new users/groups are visible. - * - * @param configName - * @exception BadRealmException if realm data structures are bad - */ - public void refresh(String configName) throws BadRealmException { - // do nothing + Realm oldRealm = realmsManager.getFromLoadedRealms(name); + if (!oldRealm.getClass().equals(realm.getClass())) { + // Would never happen unless bug in realm subclass + throw new Error("Incompatible class " + realm.getClass() + " in replacement realm " + name); + } + realm.setName(oldRealm.getName()); + realmsManager.putIntoLoadedRealms(name, realm); + + _logger.log(FINER, realmUpdated, new Object[] { realm.getName() }); } /** - * Adds new user to file realm. User cannot exist already. - * - * @param name User name. - * @param password Cleartext password for the user. - * @param groupList List of groups to which user belongs. - * @throws BadRealmException If there are problems adding user. - * @throws IASSecurityException + * Replace a Realm instance. Can be used by a Realm subclass to replace a previously initialized + * instance of itself. Future getInstance requests will then obtain the new instance. * - */ - public abstract void addUser(String name, char[] password, String[] groupList) throws BadRealmException, IASSecurityException; - - /** - * Remove user from file realm. User must exist. + *

+ * Minimal error checking is done. The realm being replaced must already exist (instantiate() was + * previously called), the new instance must be fully initialized properly and it must of course be + * of the same class as the previous instance. * - * @param name User name. - * @throws NoSuchUserException If user does not exist. - * @throws BadRealmException + * @param configName + * @param realm The new realm instance. + * @param name The (previously instantiated) name for this realm. * */ - public abstract void removeUser(String name) throws NoSuchUserException, BadRealmException; + protected static synchronized void updateInstance(String configName, Realm realm, String name) { + RealmsManager realmsManager = tryGetRealmsManager(); + Realm oldRealm = realmsManager.getFromLoadedRealms(configName, name); + if (!oldRealm.getClass().equals(realm.getClass())) { + // Would never happen unless bug in realm subclass + throw new Error("Incompatible class " + realm.getClass() + " in replacement realm " + name); + } + + realm.setName(oldRealm.getName()); + realmsManager.putIntoLoadedRealms(configName, name, realm); + + _logger.log(FINER, realmUpdated, new Object[] { realm.getName() }); + } + + + + + // ---[ Private methods ]------------------------------------------------ + + /** - * Update data for an existing user. User must exist. - * - * @param name Current name of the user to update. - * @param newName New name to give this user. It can be the same as the original name. Otherwise it - * must be a new user name which does not already exist as a user. - * @param password Cleartext password for the user. If non-null the user password is changed to this - * value. If null, the original password is retained. - * @param groups Array of groups to which user belongs. - * @throws BadRealmException If there are problems adding user. - * @throws NoSuchUserException If user does not exist. - * @throws IASSecurityException + * Instantiates a Realm class of the given type and invokes its init() * */ - public abstract void updateUser(String name, String newName, char[] password, String[] groups) throws NoSuchUserException, BadRealmException, IASSecurityException; + private static synchronized Realm doInstantiate(String name, String className, Properties props) throws BadRealmException { + + ServiceLocator serviceLocator = Globals.getDefaultHabitat(); + try { + RealmsManager realmsManager = getRealmsManager(); + + // Try a HK2 route first + Realm realm = serviceLocator.getService(Realm.class, name); + if (realm == null) { + try { + // TODO: workaround here. Once fixed in V3 we should be able to use + // Context ClassLoader instead. + realm = (Realm) serviceLocator.getService(ClassLoaderHierarchy.class) + .getCommonClassLoader() + .loadClass(className) + .newInstance(); + } catch (ClassNotFoundException ex) { + realm = (Realm) Class.forName(className).newInstance(); + } + } + + realm.setName(name); + realm.init(props); + + if (realmsManager == null) { + throw new BadRealmException("Unable to locate RealmsManager Service"); + } + + _logger.log(FINER, realmCreated, new Object[] { name, className }); + + return realm; + } catch (NoSuchRealmException | InstantiationException | IllegalAccessException | ClassNotFoundException ex) { + throw new BadRealmException(ex); + } + } + /** - * @return true if the realm implementation support User Management (add,remove,update user) + * This is a private method for getting realm instance. If realm does not exist, then it will not + * return null rather than throw exception. + * + * @param name identifies the realm + * @return the requested realm */ - public abstract boolean supportsUserManagement(); + private static synchronized Realm _getInstance(String name) { + return tryGetRealmsManager()._getInstance(name); + } /** - * Persist the realm data to permanent storage + * This is a private method for getting realm instance. If realm does not exist, then it will not + * return null rather than throw exception. * - * @throws com.sun.enterprise.security.auth.realm.BadRealmException + * @param name identifies the realm + * @return the requested realm */ - public abstract void persist() throws BadRealmException; + private static synchronized Realm _getInstance(String configName, String name) { + return tryGetRealmsManager()._getInstance(configName, name); + } + + private static void registerRealmStatsProvier() { + if (realmStatsProvier == null) { + getRealmStatsProvier(); + StatsProviderManager.register("security", SERVER, "security/realm", realmStatsProvier); + } + } + + } diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmConfig.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmConfig.java index 1ddb6cf1cfe..42d5d021661 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmConfig.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmConfig.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm; import static com.sun.enterprise.security.SecurityLoggerInfo.noRealmsError; @@ -68,24 +68,20 @@ public static void createRealms(String defaultRealm, List realms) { } public static void createRealms(String defaultRealm, List realms, String configName) { - assert (realms != null); - String goodRealm = null; // need at least one good realm - for (AuthRealm aRealm : realms) { - String realmName = aRealm.getName(); - String realmClass = aRealm.getClassname(); - assert (realmName != null); - assert (realmClass != null); + for (AuthRealm realm : realms) { + String realmName = realm.getName(); + String realmClass = realm.getClassname(); try { - List realmProps = aRealm.getProperty(); - Properties props = new Properties(); - for (Property realmProp : realmProps) { - props.setProperty(realmProp.getName(), realmProp.getValue()); + List realmProperties = realm.getProperty(); + Properties properties = new Properties(); + for (Property realmProperty : realmProperties) { + properties.setProperty(realmProperty.getName(), realmProperty.getValue()); } - Realm.instantiate(realmName, realmClass, props, configName); + Realm.instantiate(realmName, realmClass, properties, configName); if (logger.isLoggable(FINE)) { logger.fine("Configured realm: " + realmName); } @@ -105,13 +101,13 @@ public static void createRealms(String defaultRealm, List realms, Str if (goodRealm == null) { logger.severe(noRealmsError); - } else { try { Realm.getInstance(defaultRealm); } catch (Exception e) { defaultRealm = goodRealm; } + Realm.setDefaultRealm(defaultRealm); if (logger.isLoggable(FINE)) { logger.fine("Default realm is set to: " + defaultRealm); diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmsManagerStore.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmsManagerStore.java new file mode 100644 index 00000000000..e0982a1f677 --- /dev/null +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/RealmsManagerStore.java @@ -0,0 +1,88 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates +package com.sun.enterprise.security.auth.realm; + +import java.lang.ref.WeakReference; + +import org.glassfish.internal.api.Globals; + +/** + * This class stores a static, but weak, reference to the realms manager. + * + * @see RealmsManager + * + * @author Arjan Tijms (factored out from Realm) + * + */ +public class RealmsManagerStore { + + private static WeakReference realmsManager = new WeakReference(null); + + static RealmsManager tryGetRealmsManager() { + RealmsManager manager = getRealmsManager(); + if (manager == null) { + throw new RuntimeException("Unable to locate RealmsManager Service"); + } + + return manager; + } + + static RealmsManager getRealmsManager() { + if (realmsManager.get() != null) { + return realmsManager.get(); + } + + return _getRealmsManager(); + } + + static synchronized RealmsManager _getRealmsManager() { + if (realmsManager.get() == null) { + if (Globals.getDefaultHabitat() != null) { + realmsManager = new WeakReference(Globals.get(RealmsManager.class)); + } else { + return null; + } + } + + return realmsManager.get(); + } + +} diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/User.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/User.java index b16abed76ad..a9a07d98cd6 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/User.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/User.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm; import java.security.Principal; @@ -58,7 +58,6 @@ * * @author Harish Prabandham */ - public interface User extends Principal { /** diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/certificate/CertificateRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/certificate/CertificateRealm.java index 399cd5d1dd9..b55ac4db3c5 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/certificate/CertificateRealm.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/certificate/CertificateRealm.java @@ -37,16 +37,25 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm.certificate; +import static java.util.Arrays.asList; +import static java.util.logging.Level.FINEST; + +import java.security.Principal; +import java.util.Collections; import java.util.Enumeration; +import java.util.LinkedList; +import java.util.List; import java.util.Properties; import java.util.Set; import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; import org.glassfish.security.common.Group; +import org.jvnet.hk2.annotations.Service; import com.sun.enterprise.security.BaseRealm; import com.sun.enterprise.security.SecurityContext; @@ -56,16 +65,6 @@ import com.sun.enterprise.security.auth.realm.NoSuchRealmException; import com.sun.enterprise.security.auth.realm.NoSuchUserException; -import java.security.Principal; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedList; -import java.util.logging.Level; -import javax.security.auth.callback.Callback; - - -import org.jvnet.hk2.annotations.Service; - /** * Realm wrapper for supporting certificate authentication. * @@ -98,7 +97,8 @@ public final class CertificateRealm extends BaseRealm { // Descriptive string of the authentication type of this realm. public static final String AUTH_TYPE = "certificate"; - private LinkedList defaultGroups = new LinkedList<>(); + + private List defaultGroups = new LinkedList<>(); /** * Initialize a realm with some properties. This can be used when instantiating realms from their descriptions. This @@ -115,7 +115,7 @@ protected void init(Properties props) throws BadRealmException, NoSuchRealmExcep String[] groups = addAssignGroups(null); if (groups != null && groups.length > 0) { - defaultGroups.addAll(Arrays.asList(groups)); + defaultGroups.addAll(asList(groups)); } String jaasCtx = props.getProperty(JAAS_CONTEXT_PARAM); @@ -134,24 +134,19 @@ protected void init(Properties props) throws BadRealmException, NoSuchRealmExcep public String getAuthType() { return AUTH_TYPE; } - /** * Returns the name of all the groups that this user belongs to. * - * @param username Name of the user in this realm whose group listing - * is needed. + * @param username Name of the user in this realm whose group listing is needed. * @return Enumeration of group names (strings). - * @exception InvalidOperationException thrown if the realm does not - * support this operation - e.g. Certificate realm does not support - * this operation. + * @exception InvalidOperationException thrown if the realm does not support this operation - e.g. Certificate realm + * does not support this operation. * @throws com.sun.enterprise.security.auth.realm.NoSuchUserException * */ @Override - public Enumeration getGroupNames(String username) - throws NoSuchUserException, InvalidOperationException - { + public Enumeration getGroupNames(String username) throws NoSuchUserException, InvalidOperationException { // This is called during web container role check, not during // EJB container role cheks... fix RI for consistency. @@ -173,21 +168,19 @@ public void authenticate(Subject subject, Principal principal) { // 4646134 for reasons why this matters. String name = principal.getName(); - if (_logger.isLoggable(Level.FINEST)) { - _logger.log(Level.FINEST, "Certificate realm setting up security context for: {0}", name); - } + _logger.log(FINEST, "Certificate realm setting up security context for: {0}", name); if (defaultGroups != null) { - Set principalSet = subject.getPrincipals(); - for (String groupName : defaultGroups) { - principalSet.add(new Group(groupName)); - } - } + Set principalSet = subject.getPrincipals(); + for (String groupName : defaultGroups) { + principalSet.add(new Group(groupName)); + } + } if (!subject.getPrincipals().isEmpty()) { subject.getPublicCredentials().add(new DistinguishedPrincipalCredential(principal)); } - + SecurityContext.setCurrent(new SecurityContext(name, subject)); } @@ -214,9 +207,8 @@ public String getModuleID() { } /** - * Set the fully qualified module name. The module name consists - * of the application name (if not a singleton) followed by a '#' - * and the name of the module. + * Set the fully qualified module name. The module name consists of the application name (if not a singleton) followed + * by a '#' and the name of the module. * * @param moduleID */ diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealm.java index 09f444938e7..9514cc7fa61 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealm.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealm.java @@ -37,20 +37,20 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm.file; import static com.sun.enterprise.security.common.Util.isEmbeddedServer; import static com.sun.enterprise.security.common.Util.writeConfigFileToTempDir; import static java.util.Arrays.asList; import static java.util.Collections.enumeration; +import static java.util.logging.Level.FINE; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Properties; -import java.util.logging.Level; import org.glassfish.internal.api.RelativePathResolver; import org.glassfish.security.common.FileRealmStorageManager; @@ -179,8 +179,8 @@ protected void init(Properties props) throws BadRealmException, NoSuchRealmExcep } setProperty(BaseRealm.JAAS_CONTEXT_PARAM, jaasCtx); - _logger.log(Level.FINE, "FileRealm : " + PARAM_KEYFILE + "={0}", file); - _logger.log(Level.FINE, "FileRealm : " + JAAS_CONTEXT_PARAM + "={0}", jaasCtx); + _logger.log(FINE, "FileRealm : " + PARAM_KEYFILE + "={0}", file); + _logger.log(FINE, "FileRealm : " + JAAS_CONTEXT_PARAM + "={0}", jaasCtx); try { if (isEmbeddedServer()) { diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealmUser.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealmUser.java index c75eb55938d..6c22b705f2a 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealmUser.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/file/FileRealmUser.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm.file; import java.util.Enumeration; @@ -55,14 +55,10 @@ */ public class FileRealmUser implements User { - FileRealmStorageManager.User user; - Hashtable attributes = new Hashtable<>(); - String realm; + private FileRealmStorageManager.User user; + private Hashtable attributes = new Hashtable<>(); + private String realm; - /** - * Constructor. - * - */ public FileRealmUser(FileRealmStorageManager.User user, String realm) { this.user = user; this.realm = realm; diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/ldap/LDAPRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/ldap/LDAPRealm.java index d2fbcc12022..aef41299aad 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/ldap/LDAPRealm.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/ldap/LDAPRealm.java @@ -37,12 +37,24 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm.ldap; import static java.util.logging.Level.FINE; - -import java.util.*; +import static java.util.logging.Level.FINEST; +import static java.util.logging.Level.WARNING; +import static javax.naming.Context.SECURITY_CREDENTIALS; +import static javax.naming.Context.SECURITY_PRINCIPAL; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; import java.util.logging.Level; import java.util.regex.Matcher; @@ -92,17 +104,16 @@ * value is uid=%s where %s is expanded to the username. *

  • group-base-dn - The base DN to use for group searches. By default its value is the same as base-dn. *
  • group-search-filter - The LDAP filter to use for searching group membership of a given user. The default value is - * + * * uniquemember=%d where %d is expanded to the DN of the user found by the user search. *
  • group-target - The attribute which value(s) are interpreted as group membership names of the user. Default value - * is cn. + * is cn. *
  • search-bind-dn - The dn of ldap user. optional and no default value. *
  • search-bind-password - The password of search-bind-dn.optional and no default value. *
  • pool-size - The JNDI ldap connection pool size. * * * @see com.sun.enterprise.security.auth.login.LDAPLoginModule - * */ @Service public final class LDAPRealm extends BaseRealm { @@ -200,60 +211,61 @@ public synchronized void init(Properties props) throws BadRealmException, NoSuch if (!MODE_DEFAULT.equals(mode)) { throw new BadRealmException(sm.getString("ldaprealm.badmode", mode)); } - this.setProperty(PARAM_MODE, mode); + setProperty(PARAM_MODE, mode); String ctxF = props.getProperty(PARAM_JNDICF, JNDICF_DEFAULT); - this.setProperty(PARAM_JNDICF, ctxF); + setProperty(PARAM_JNDICF, ctxF); ldapBindProps.setProperty(Context.INITIAL_CONTEXT_FACTORY, ctxF); String searchFilter = props.getProperty(PARAM_SEARCH_FILTER, SEARCH_FILTER_DEFAULT); - this.setProperty(PARAM_SEARCH_FILTER, searchFilter); + setProperty(PARAM_SEARCH_FILTER, searchFilter); String grpDN = props.getProperty(PARAM_GRPDN, dn); - this.setProperty(PARAM_GRPDN, grpDN); + setProperty(PARAM_GRPDN, grpDN); String grpSearchFilter = props.getProperty(PARAM_GRP_SEARCH_FILTER, GRP_SEARCH_FILTER_DEFAULT); - this.setProperty(PARAM_GRP_SEARCH_FILTER, grpSearchFilter); + setProperty(PARAM_GRP_SEARCH_FILTER, grpSearchFilter); String dynGrpSearchFilter = props.getProperty(PARAM_DYNAMIC_GRP_FILTER, SEARCH_FILTER_DEFAULT); - this.setProperty(PARAM_DYNAMIC_GRP_FILTER, dynGrpSearchFilter); + setProperty(PARAM_DYNAMIC_GRP_FILTER, dynGrpSearchFilter); String grpTarget = props.getProperty(PARAM_GRP_TARGET, GRP_TARGET_DEFAULT); - this.setProperty(PARAM_GRP_TARGET, grpTarget); + setProperty(PARAM_GRP_TARGET, grpTarget); String dynGrpTarget = props.getProperty(PARAM_DYNAMIC_GRP_TARGET, DYNAMIC_GRP_TARGET_DEFAULT); - this.setProperty(PARAM_DYNAMIC_GRP_TARGET, dynGrpTarget); + setProperty(PARAM_DYNAMIC_GRP_TARGET, dynGrpTarget); String objectFactory = props.getProperty(DYNAMIC_GROUP_FACTORY_OBJECT_PROPERTY, DYNAMIC_GROUP_OBJECT_FACTORY); - this.setProperty(DYNAMIC_GROUP_FACTORY_OBJECT_PROPERTY, objectFactory); + setProperty(DYNAMIC_GROUP_FACTORY_OBJECT_PROPERTY, objectFactory); ldapBindProps.setProperty(DYNAMIC_GROUP_FACTORY_OBJECT_PROPERTY, objectFactory); String stateFactory = props.getProperty(DYNAMIC_GROUP_STATE_FACTORY_PROPERTY, DYNAMIC_GROUP_STATE_FACTORY); - this.setProperty(DYNAMIC_GROUP_STATE_FACTORY_PROPERTY, stateFactory); + setProperty(DYNAMIC_GROUP_STATE_FACTORY_PROPERTY, stateFactory); ldapBindProps.setProperty(DYNAMIC_GROUP_STATE_FACTORY_PROPERTY, stateFactory); String bindDN = props.getProperty(PARAM_BINDDN); if (bindDN != null) { - this.setProperty(PARAM_BINDDN, bindDN); - ldapBindProps.setProperty(Context.SECURITY_PRINCIPAL, bindDN); + setProperty(PARAM_BINDDN, bindDN); + ldapBindProps.setProperty(SECURITY_PRINCIPAL, bindDN); } + String bindPWD = props.getProperty(PARAM_BINDPWD); if (bindPWD != null) { - // If the passwors is aliased, de-alias it + // If the password is aliased, de-alias it try { bindPWD = RelativePathResolver.getRealPasswordFromAlias(bindPWD); } catch (Exception ex) { - _logger.log(Level.WARNING, "ldaprealm.pwd.dealiasing.failed", ex); + _logger.log(WARNING, "ldaprealm.pwd.dealiasing.failed", ex); } - this.setProperty(PARAM_BINDPWD, bindPWD); - ldapBindProps.setProperty(Context.SECURITY_CREDENTIALS, bindPWD); + + setProperty(PARAM_BINDPWD, bindPWD); + ldapBindProps.setProperty(SECURITY_CREDENTIALS, bindPWD); } - Enumeration penum = props.propertyNames(); + Enumeration penum = props.propertyNames(); while (penum.hasMoreElements()) { String propName = (String) penum.nextElement(); - if (propName.startsWith("java.naming.") || propName.startsWith("javax.security.") - || propName.startsWith("com.sun.jndi.ldap.")) { + if (propName.startsWith("java.naming.") || propName.startsWith("javax.security.") || propName.startsWith("com.sun.jndi.ldap.")) { ldapBindProps.setProperty(propName, props.getProperty(propName)); } else if (propName.startsWith(SUN_JNDI_POOL_) && !SUN_JNDI_POOL_MAXSIZE.equals(propName)) { if (System.getProperty(propName) == null) { @@ -264,12 +276,14 @@ public synchronized void init(Properties props) throws BadRealmException, NoSuch String poolSize = Integer.getInteger(PARAM_POOLSIZE, POOLSIZE_DEFAULT).toString(); String sunPoolSizeStr = props.getProperty(SUN_JNDI_POOL_MAXSIZE, poolSize); + // Precedence rule: SUN_JNDI_POOL_MAXSIZE > PARAM_POOLSIZE > POOLSIZE_DEFAULT try { sunPoolSizeStr = Integer.valueOf(sunPoolSizeStr).toString(); } catch (Exception ex) { sunPoolSizeStr = poolSize; } + if (System.getProperty(SUN_JNDI_POOL_MAXSIZE) == null) { System.setProperty(SUN_JNDI_POOL_MAXSIZE, sunPoolSizeStr); } @@ -288,8 +302,8 @@ public synchronized void init(Properties props) throws BadRealmException, NoSuch if (_logger.isLoggable(FINE)) { Properties tempProps = (Properties) ldapBindProps.clone(); - tempProps.remove(Context.SECURITY_CREDENTIALS); - _logger.log(Level.FINE, "LDAPRealm : {0}", tempProps); + tempProps.remove(SECURITY_CREDENTIALS); + _logger.log(FINE, "LDAPRealm : {0}", tempProps); } groupCache = new HashMap<>(); @@ -306,20 +320,21 @@ public String getAuthType() { return AUTH_TYPE; } - private String[] addMappedGroupNames(String[] grpList) { - + private String[] addMappedGroupNames(String[] groups) { if (groupMapper == null) { - return grpList; + return groups; } + List finalresult = new ArrayList<>(); - for (String grp : grpList) { + for (String group : groups) { List result = new ArrayList<>(); - groupMapper.getMappedGroups(grp, result); - finalresult.add(grp); + groupMapper.getMappedGroups(group, result); + finalresult.add(group); if (!result.isEmpty()) { finalresult.addAll(result); } } + return finalresult.toArray(new String[finalresult.size()]); } @@ -342,8 +357,8 @@ private List getGroups(String userDN) { ctx = new InitialDirContext(getLdapBindProps()); String _username = userDN; - LdapName name = new LdapName(userDN); //Ignoring the exception to suppot simple group names as userDN - //Issue GLASSFISH-19595 + LdapName name = new LdapName(userDN); // Ignoring the exception to suppot simple group names as userDN + // Issue GLASSFISH-19595 for (Rdn rdn : name.getRdns()) { if (rdn.getType().equalsIgnoreCase("CN")) { _username = rdn.getValue().toString(); @@ -376,13 +391,13 @@ private List getGroups(String userDN) { groupsList.addAll(dynamicGroupSearch(ctx, getProperty(PARAM_GRPDN), dynMember, dynFilter, getProperty(PARAM_GRP_TARGET))); return groupsList; } catch (Exception e) { - _logger.log(Level.WARNING, "ldaprealm.groupsearcherror", e); + _logger.log(WARNING, "ldaprealm.groupsearcherror", e); } finally { if (ctx != null) { try { ctx.close(); } catch (NamingException e) { - _logger.log(Level.WARNING, "ldaprealm.exception", e); + _logger.log(WARNING, "ldaprealm.exception", e); } } } @@ -396,7 +411,7 @@ private List getGroups(String userDN) { * @param username Name of the user in this realm whose group listing is needed. * @return Enumeration of group names (strings). * @exception InvalidOperationException thrown if the realm does not support this operation - e.g. Certificate realm - * does not support this operation. + * does not support this operation. */ @Override public Enumeration getGroupNames(String username) throws InvalidOperationException, NoSuchUserException { @@ -407,8 +422,8 @@ public Enumeration getGroupNames(String username) throws InvalidOperationExcepti if (searchedGrps != null) { return Collections.enumeration(searchedGrps); } - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "No groups available for: " + username); + if (_logger.isLoggable(FINE)) { + _logger.log(FINE, "No groups available for: " + username); } // we don't load group here as we need to bind ctx to user with // password before doing that and password is not available here @@ -505,8 +520,8 @@ public String[] findAndBind(String _username, char[] _password) throws LoginExce } } - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "LDAP:Group search filter: {0}", srcFilter); + if (_logger.isLoggable(FINE)) { + _logger.log(FINE, "LDAP:Group search filter: {0}", srcFilter); StringBuilder gb = new StringBuilder(); gb.append("Group memberships found: "); if (grpList.length > 0) { @@ -516,16 +531,16 @@ public String[] findAndBind(String _username, char[] _password) throws LoginExce } else { gb.append("(null)"); } - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "LDAP: {0}", gb.toString()); + if (_logger.isLoggable(FINE)) { + _logger.log(FINE, "LDAP: {0}", gb.toString()); } } grpList = addAssignGroups(grpList); grpList = this.addMappedGroupNames(grpList); setGroupNames(_username, grpList); - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "LDAP: login succeeded for: {0}", _username); + if (_logger.isLoggable(FINE)) { + _logger.log(FINE, "LDAP: login succeeded for: {0}", _username); } return grpList; @@ -536,8 +551,8 @@ public String[] findAndBind(String _username, char[] _password) throws LoginExce * */ private String userSearch(DirContext ctx, String baseDN, String filter) { - if (_logger.isLoggable(Level.FINEST)) { - _logger.log(Level.FINE, "search: baseDN: {0} filter: {1}", new Object[]{baseDN, filter}); + if (_logger.isLoggable(FINEST)) { + _logger.log(FINE, "search: baseDN: {0} filter: {1}", new Object[] { baseDN, filter }); } String foundDN = null; @@ -554,7 +569,7 @@ private String userSearch(DirContext ctx, String baseDN, String filter) { SearchResult res = (SearchResult) namingEnum.next(); StringBuilder sb = new StringBuilder(); - //for dn name with '/' + // for dn name with '/' CompositeName compDN = new CompositeName(res.getName()); String ldapDN = compDN.get(0); sb.append(ldapDN); @@ -564,13 +579,13 @@ private String userSearch(DirContext ctx, String baseDN, String filter) { sb.append(baseDN); } foundDN = sb.toString(); - if (_logger.isLoggable(Level.FINEST)) { - _logger.log(Level.FINE, "Found user DN: {0}", foundDN); + if (_logger.isLoggable(FINEST)) { + _logger.log(FINE, "Found user DN: {0}", foundDN); } } } catch (Exception e) { - _logger.log(Level.WARNING, "ldaprealm.searcherror", filter); - _logger.log(Level.WARNING, "security.exception", e); + _logger.log(WARNING, "ldaprealm.searcherror", filter); + _logger.log(WARNING, "security.exception", e); } finally { if (namingEnum != null) { try { @@ -590,19 +605,19 @@ private String userSearch(DirContext ctx, String baseDN, String filter) { private boolean bindAsUser(String bindDN, char[] password) { boolean bindSuccessful = false; - Properties p = getLdapBindProps(); + Properties bindProperties = getLdapBindProps(); - p.put(Context.SECURITY_PRINCIPAL, bindDN); - p.put(Context.SECURITY_CREDENTIALS, new String(password)); + bindProperties.put(SECURITY_PRINCIPAL, bindDN); + bindProperties.put(SECURITY_CREDENTIALS, new String(password)); DirContext ctx = null; try { - ctx = new InitialDirContext(p); + ctx = new InitialDirContext(bindProperties); bindSuccessful = true; } catch (Exception e) { - if (_logger.isLoggable(Level.FINEST)) { - _logger.log(Level.FINEST, "Error binding to directory as: {0}", bindDN); - _logger.log(Level.FINEST, "Exception from JNDI: {0}", e.toString()); + if (_logger.isLoggable(FINEST)) { + _logger.log(FINEST, "Error binding to directory as: {0}", bindDN); + _logger.log(FINEST, "Exception from JNDI: {0}", e.toString()); } } finally { if (ctx != null) { @@ -612,6 +627,7 @@ private boolean bindAsUser(String bindDN, char[] password) { } } } + return bindSuccessful; } @@ -619,9 +635,7 @@ private boolean bindAsUser(String bindDN, char[] password) { * Search for group membership using the given connection. * */ - private List dynamicGroupSearch( - DirContext ctx, String baseDN, String memberOfAttr, String filter, String target - ) { + private List dynamicGroupSearch(DirContext ctx, String baseDN, String memberOfAttr, String filter, String target) { List groupList = new ArrayList<>(); String[] targets = new String[] { memberOfAttr }; @@ -653,9 +667,10 @@ private List dynamicGroupSearch( } } } catch (Exception e) { - _logger.log(Level.WARNING, "ldaprealm.searcherror", filter); - _logger.log(Level.WARNING, "security.exception", e); + _logger.log(WARNING, "ldaprealm.searcherror", filter); + _logger.log(WARNING, "security.exception", e); } + return groupList; } @@ -674,8 +689,7 @@ private List groupSearch(DirContext ctx, String baseDN, String filter, S ctls.setReturningAttributes(targets); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); - NamingEnumeration e = ctx.search(baseDN, filter.replaceAll(Matcher.quoteReplacement("\\"), Matcher.quoteReplacement("\\\\")), - ctls); + NamingEnumeration e = ctx.search(baseDN, filter.replaceAll(Matcher.quoteReplacement("\\"), Matcher.quoteReplacement("\\\\")), ctls); while (e.hasMore()) { SearchResult res = (SearchResult) e.next(); @@ -688,8 +702,8 @@ private List groupSearch(DirContext ctx, String baseDN, String filter, S } } catch (Exception e) { - _logger.log(Level.WARNING, "ldaprealm.searcherror", filter); - _logger.log(Level.WARNING, "security.exception", e); + _logger.log(WARNING, "ldaprealm.searcherror", filter); + _logger.log(WARNING, "security.exception", e); } return groupList; diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/package-info.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/package-info.java new file mode 100644 index 00000000000..2338d86e306 --- /dev/null +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/package-info.java @@ -0,0 +1,54 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. + * All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the + * "Classpath" exception as provided by the Payara Foundation in the GPL + * Version 2 section of the License file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +/** + * This package contains the Realms used by Payara for its native identity stores. + * + *

    + * Realms in Payara have to be paired with LoginModules, which are in the + * com.sun.enterprise.security.auth.login package. + * + *

    + * A Realm contains the actual credential validation functionality of an identity store, + * but can additionally contain user management (create, update delete) functionality as well. + * + */ +package com.sun.enterprise.security.auth.realm; \ No newline at end of file From 677f5d05bdd37c21209278c0b7ed755258bbc740 Mon Sep 17 00:00:00 2001 From: arjantijms Date: Fri, 15 Mar 2019 17:30:00 +0100 Subject: [PATCH 034/108] PAYARA-3539 Small cleanup cluster package - sweep 2 --- .../cluster/BootstrapSecureAdminCommand.java | 56 +-- .../admin/cluster/ClusterCommandHelper.java | 245 +++++------ .../v3/admin/cluster/CommandRunnable.java | 72 ++-- .../v3/admin/cluster/Constants.java | 3 +- .../v3/admin/cluster/CopyConfigCommand.java | 87 ++-- .../admin/cluster/CreateInstanceCommand.java | 382 +++++++++--------- .../cluster/CreateNodeConfigCommand.java | 112 +++-- .../cluster/CreateNodeImplicitCommand.java | 82 ++-- .../admin/cluster/CreateNodeSshCommand.java | 78 ++-- .../cluster/CreateRemoteNodeCommand.java | 225 ++++++----- .../v3/admin/cluster/DeleteConfigCommand.java | 116 +++--- .../admin/cluster/DeleteInstanceCommand.java | 130 +++--- .../cluster/DeleteNodeConfigCommand.java | 80 ++-- .../cluster/DeleteNodeRemoteCommand.java | 176 ++++---- .../admin/cluster/DeleteNodeSshCommand.java | 57 ++- .../v3/admin/cluster/ExportSyncBundle.java | 202 +++++---- 16 files changed, 1122 insertions(+), 981 deletions(-) diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/BootstrapSecureAdminCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/BootstrapSecureAdminCommand.java index 284e4126bc5..8fb0897c41e 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/BootstrapSecureAdminCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/BootstrapSecureAdminCommand.java @@ -37,20 +37,33 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.v3.admin.cluster; -import com.sun.enterprise.config.serverbeans.Domain; +import static org.glassfish.api.ActionReport.ExitCode.FAILURE; +import static org.glassfish.api.ActionReport.ExitCode.SUCCESS; +import static org.glassfish.api.admin.RestEndpoint.OpType.POST; + import java.io.File; import java.io.IOException; -import org.glassfish.api.ActionReport; -import org.glassfish.api.admin.*; + import javax.inject.Inject; -import org.jvnet.hk2.annotations.Service; +import org.glassfish.api.ActionReport; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.Payload; +import org.glassfish.api.admin.RestEndpoint; +import org.glassfish.api.admin.RestEndpoints; +import org.glassfish.api.admin.RuntimeType; +import org.glassfish.api.admin.ServerEnvironment; import org.glassfish.hk2.api.PerLookup; import org.glassfish.hk2.api.PostConstruct; +import org.jvnet.hk2.annotations.Service; + +import com.sun.enterprise.config.serverbeans.Domain; /** * Bootstraps secure admin on a new instance by downloading the minimum files @@ -60,10 +73,10 @@ */ @Service(name="_bootstrap-secure-admin") @PerLookup -@ExecuteOn(value={RuntimeType.DAS}) +@ExecuteOn(value=RuntimeType.DAS) @RestEndpoints({ @RestEndpoint(configBean=Domain.class, - opType=RestEndpoint.OpType.POST, + opType=POST, path="_bootstrap-secure-admin", description="_bootstrap-secure-admin") }) @@ -75,34 +88,29 @@ public class BootstrapSecureAdminCommand implements AdminCommand, PostConstruct private File[] bootstrappedFiles = null; @Inject - private ServerEnvironment env; - - + private ServerEnvironment serverEnvironment; + @Override public void postConstruct() { - bootstrappedFiles = new File[] { - env.getJKS(), - env.getTrustStore() - }; + bootstrappedFiles = new File[] { serverEnvironment.getJKS(), serverEnvironment.getTrustStore() }; } @Override public void execute(AdminCommandContext context) { - final ActionReport report = context.getActionReport(); - final Payload.Outbound outboundPayload = context.getOutboundPayload(); - final File instanceRoot = env.getInstanceRoot(); + ActionReport report = context.getActionReport(); + Payload.Outbound outboundPayload = context.getOutboundPayload(); + File instanceRoot = serverEnvironment.getInstanceRoot(); try { - for (File f : bootstrappedFiles) { + for (File bootstrappedFile : bootstrappedFiles) { outboundPayload.attachFile( - DOWNLOADED_FILE_MIME_TYPE, - instanceRoot.toURI().relativize(f.toURI()), - DOWNLOAD_DATA_REQUEST_NAME, - f); + DOWNLOADED_FILE_MIME_TYPE, + instanceRoot.toURI().relativize(bootstrappedFile.toURI()), + DOWNLOAD_DATA_REQUEST_NAME, bootstrappedFile); } - report.setActionExitCode(ActionReport.ExitCode.SUCCESS); + report.setActionExitCode(SUCCESS); } catch (IOException ex) { - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setFailureCause(ex); } } diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/ClusterCommandHelper.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/ClusterCommandHelper.java index 8d09c6bbde7..1e533e8ac89 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/ClusterCommandHelper.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/ClusterCommandHelper.java @@ -38,18 +38,17 @@ * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.v3.admin.cluster; +import static java.lang.Math.min; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.logging.Level.FINE; +import static org.glassfish.api.ActionReport.ExitCode.FAILURE; +import static org.glassfish.api.ActionReport.ExitCode.SUCCESS; +import static org.glassfish.api.ActionReport.ExitCode.WARNING; -import com.sun.enterprise.admin.remote.RemoteRestAdminCommand; -import com.sun.enterprise.config.serverbeans.Cluster; -import com.sun.enterprise.config.serverbeans.Config; -import com.sun.enterprise.config.serverbeans.Domain; -import com.sun.enterprise.config.serverbeans.Server; -import com.sun.enterprise.v3.admin.adapter.AdminEndpointDecider; -import fish.payara.enterprise.config.serverbeans.DeploymentGroup; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -57,11 +56,9 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; import java.util.logging.Logger; -import java.util.logging.Level; + import org.glassfish.api.ActionReport; -import org.glassfish.api.ActionReport.ExitCode; import org.glassfish.api.admin.AdminCommandContext; import org.glassfish.api.admin.CommandException; import org.glassfish.api.admin.CommandRunner; @@ -69,6 +66,12 @@ import org.glassfish.api.admin.ParameterMap; import org.glassfish.api.admin.ProgressStatus; +import com.sun.enterprise.admin.remote.RemoteRestAdminCommand; +import com.sun.enterprise.config.serverbeans.Cluster; +import com.sun.enterprise.config.serverbeans.Config; +import com.sun.enterprise.config.serverbeans.Domain; +import com.sun.enterprise.config.serverbeans.Server; +import com.sun.enterprise.v3.admin.adapter.AdminEndpointDecider; /* * ClusterCommandHelper is a helper class that knows how to execute an @@ -83,9 +86,9 @@ public class ClusterCommandHelper { private static final String NL = System.getProperty("line.separator"); + private static final int ADMIN_DEFAULT_POOL_SIZE = 5; private final Domain domain; - private final CommandRunner runner; private ProgressStatus progress; @@ -100,63 +103,41 @@ public ClusterCommandHelper(Domain domain, CommandRunner runner) { this.domain = domain; this.runner = runner; } - /** - * Loop through all instances in a cluster and execute a command for - * each one. + + /** + * Loop through all instances in a cluster and execute a command for each one. * - * @param command The string of the command to run. The instance - * name will be used as the operand for the command. - * @param map A map of parameters to use for the command. May be - * null if no parameters. When the command is - * executed for a server instance, the instance name - * is set as the DEFAULT parameter (operand) - * @param targetName The name of the cluster or deployment group containing the instances - * to run the command against. - * @param context The AdminCommandContext to use when executing the - * command. - * @param verbose true for more verbose output - * @return An ActionReport containing the results + * @param command The string of the command to run. The instance name will be used as the operand for the command. + * @param map A map of parameters to use for the command. May be null if no parameters. When the command is executed for + * a server instance, the instance name is set as the DEFAULT parameter (operand) + * @param targetName The name of the cluster or deployment group containing the instances to run the command against. + * @param context The AdminCommandContext to use when executing the command. + * @param verbose true for more verbose output + * @return An ActionReport containing the results * @throws CommandException */ - public ActionReport runCommand( - String command, - ParameterMap map, - String targetName, - AdminCommandContext context, - boolean verbose) throws CommandException { - return this.runCommand(command,map,targetName,context,verbose,false); + public ActionReport runCommand(String command, ParameterMap map, String targetName, AdminCommandContext context, boolean verbose) throws CommandException { + return this.runCommand(command, map, targetName, context, verbose, false); } - /** - * Loop through all instances in a cluster and execute a command for - * each one. + * Loop through all instances in a cluster and execute a command for each one. * - * @param command The string of the command to run. The instance - * name will be used as the operand for the command. - * @param map A map of parameters to use for the command. May be - * null if no parameters. When the command is - * executed for a server instance, the instance name - * is set as the DEFAULT parameter (operand) - * @param targetName The name of the cluster or deployment group containing the instances - * to run the command against. - * @param context The AdminCommandContext to use when executing the - * command. - * @param verbose true for more verbose output - * @param rolling Whether calls should be serialized to help with rolling restarts - * @return An ActionReport containing the results + * @param command The string of the command to run. The instance name will be used as the operand for the command. + * @param map A map of parameters to use for the command. May be null if no parameters. When the command is executed for + * a server instance, the instance name is set as the DEFAULT parameter (operand) + * @param targetName The name of the cluster or deployment group containing the instances to run the command against. + * @param context The AdminCommandContext to use when executing the command. + * @param verbose true for more verbose output + * @param rolling Whether calls should be serialized to help with rolling restarts + * @return An ActionReport containing the results * @throws CommandException */ - public ActionReport runCommand( - String command, - ParameterMap map, - String targetName, - AdminCommandContext context, - boolean verbose, boolean rolling) throws CommandException { + public ActionReport runCommand(String command, ParameterMap map, String targetName, AdminCommandContext context, boolean verbose, boolean rolling) throws CommandException { // When we started - final long startTime = System.currentTimeMillis(); + long startTime = System.currentTimeMillis(); Logger logger = context.getLogger(); ActionReport report = context.getActionReport(); @@ -164,11 +145,8 @@ public ActionReport runCommand( // Get the cluster specified by clusterName Cluster cluster = domain.getClusterNamed(targetName); if (cluster == null) { - DeploymentGroup dg = domain.getDeploymentGroupNamed(targetName); - if (dg == null) { - String msg = Strings.get("cluster.command.unknownCluster", - targetName); - throw new CommandException(msg); + if (domain.getDeploymentGroupNamed(targetName) == null) { + throw new CommandException(Strings.get("cluster.command.unknownCluster", targetName)); } } @@ -177,9 +155,8 @@ public ActionReport runCommand( // If the list of servers is empty, say so if (targetServers == null || targetServers.isEmpty()) { - report.setActionExitCode(ExitCode.SUCCESS); - report.setMessage(Strings.get("cluster.command.noInstances", - targetName)); + report.setActionExitCode(SUCCESS); + report.setMessage(Strings.get("cluster.command.noInstances", targetName)); return report; } int nInstances = targetServers.size(); @@ -189,7 +166,6 @@ public ActionReport runCommand( StringBuilder failedServerNames = new StringBuilder(); StringBuilder succeededServerNames = new StringBuilder(); List waitingForServerNames = new ArrayList<>(); - String msg; ReportResult reportResult = new ReportResult(); boolean failureOccurred = false; progress = context.getProgressStatus(); @@ -197,23 +173,20 @@ public ActionReport runCommand( // Save command output to return in ActionReport StringBuilder output = new StringBuilder(); - // Optimize the oder of server instances to avoid clumping on nodes - if (logger.isLoggable(Level.FINE)) - logger.fine(String.format("Original instance list %s", - serverListToString(targetServers))); + if (logger.isLoggable(FINE)) { + logger.fine(String.format("Original instance list %s", serverListToString(targetServers))); + } targetServers = optimizeServerListOrder(targetServers); // Holds responses from the threads running the command - ArrayBlockingQueue responseQueue = - new ArrayBlockingQueue(nInstances); + ArrayBlockingQueue responseQueue = new ArrayBlockingQueue<>(nInstances); int threadPoolSize = 1; if (!rolling) { // Make the thread pool use the smaller of the number of instances // or half the admin thread pool size - int adminThreadPoolSize = getAdminThreadPoolSize(); - threadPoolSize = Math.min(nInstances, adminThreadPoolSize / 2); + threadPoolSize = min(nInstances, getAdminThreadPoolSize() / 2); if (threadPoolSize < 1) { threadPoolSize = 1; @@ -226,34 +199,30 @@ public ActionReport runCommand( map = new ParameterMap(); } - msg = String.format( - "Executing %s on %d instances using a thread pool of size %d: %s", - command, nInstances, threadPoolSize, - serverListToString(targetServers)); - logger.info(msg); + + logger.info(String.format( + "Executing %s on %d instances using a thread pool of size %d: %s", command, nInstances, threadPoolSize, + serverListToString(targetServers))); - msg = Strings.get("cluster.command.executing", - command, Integer.toString(nInstances)); progress.setTotalStepCount(nInstances); - progress.progress(msg); + progress.progress(Strings.get("cluster.command.executing", command, Integer.toString(nInstances))); // Loop through instance names, construct the command for each // instance name, and hand it off to the threadpool. for (Server server : targetServers) { - String iname = server.getName(); - waitingForServerNames.add(iname); + String serverName = server.getName(); + waitingForServerNames.add(serverName); ParameterMap instanceParameterMap = new ParameterMap(map); // Set the instance name as the operand for the commnd - instanceParameterMap.set("DEFAULT", iname); + instanceParameterMap.set("DEFAULT", serverName); ActionReport instanceReport = runner.getActionReport("plain"); - instanceReport.setActionExitCode(ExitCode.SUCCESS); - CommandInvocation invocation = runner.getCommandInvocation( - command, instanceReport, context.getSubject()); - invocation.parameters(instanceParameterMap); + instanceReport.setActionExitCode(SUCCESS); + CommandInvocation invocation = runner.getCommandInvocation(command, instanceReport, context.getSubject()); + invocation.parameters(instanceParameterMap); - msg = command + " " + iname; + String msg = command + " " + serverName; logger.info(msg); if (verbose) { output.append(msg).append(NL); @@ -261,15 +230,14 @@ public ActionReport runCommand( // Wrap the command invocation in a runnable and hand it off // to the thread pool - CommandRunnable cmdRunnable = new CommandRunnable(invocation, - instanceReport, responseQueue); - cmdRunnable.setName(iname); + CommandRunnable cmdRunnable = new CommandRunnable(invocation, instanceReport, responseQueue); + cmdRunnable.setName(serverName); threadPool.execute(cmdRunnable); } - if (logger.isLoggable(Level.FINE)) - logger.fine(String.format( - "%s commands queued, waiting for responses", command)); + if (logger.isLoggable(FINE)) { + logger.fine(String.format("%s commands queued, waiting for responses", command)); + } // Make sure we don't wait longer than the admin read timeout. Set // our limit to be 3 seconds less. @@ -278,9 +246,10 @@ public ActionReport runCommand( // This should never be the case adminTimeout = 57 * 1000; } - if (logger.isLoggable(Level.FINE)) - logger.fine(String.format("Initial cluster command timeout: %d ms", - adminTimeout)); + + if (logger.isLoggable(FINE)) { + logger.fine(String.format("Initial cluster command timeout: %d ms", adminTimeout)); + } // Now go get results from the response queue. for (int n = 0; n < nInstances; n++) { @@ -290,14 +259,12 @@ public ActionReport runCommand( } CommandRunnable cmdRunnable = null; try { - - cmdRunnable = responseQueue.poll(timeLeft, TimeUnit.MILLISECONDS); + + cmdRunnable = responseQueue.poll(timeLeft, MILLISECONDS); } catch (InterruptedException e) { // This thread has been interrupted. Abort threadPool.shutdownNow(); - msg = Strings.get("cluster.command.interrupted", targetName, - Integer.toString(n), Integer.toString(nInstances), - command); + String msg = Strings.get("cluster.command.interrupted", targetName, Integer.toString(n), Integer.toString(nInstances), command); logger.warning(msg); output.append(msg).append(NL); failureOccurred = true; @@ -313,19 +280,20 @@ public ActionReport runCommand( String iname = cmdRunnable.getName(); waitingForServerNames.remove(iname); ActionReport instanceReport = cmdRunnable.getActionReport(); - if (logger.isLoggable(Level.FINE)) - logger.fine(String.format( - "Instance %d of %d (%s) has responded with %s", - n+1, nInstances, iname, instanceReport.getActionExitCode())); - if (instanceReport.getActionExitCode() != ExitCode.SUCCESS) { + if (logger.isLoggable(FINE)) { + logger.fine(String.format("Instance %d of %d (%s) has responded with %s", n + 1, nInstances, iname, instanceReport.getActionExitCode())); + } + + if (instanceReport.getActionExitCode() != SUCCESS) { // Bummer, the command had an error. Log and save output failureOccurred = true; failedServerNames.append(iname).append(" "); reportResult.failedServerNames.add(iname); - msg = iname + ": " + instanceReport.getMessage(); + String msg = iname + ": " + instanceReport.getMessage(); logger.severe(msg); output.append(msg).append(NL); msg = Strings.get("cluster.command.instancesFailed", command, iname); + progress.progress(1, msg); } else { // Command worked. Note that too. @@ -335,15 +303,14 @@ public ActionReport runCommand( } } - report.setActionExitCode(ExitCode.SUCCESS); - + report.setActionExitCode(SUCCESS); + if (failureOccurred) { report.setResultType(List.class, reportResult.failedServerNames); } else { report.setResultType(List.class, reportResult.succeededServerNames); } - // Display summary of started servers if in verbose mode or we // had one or more failures. if (succeededServerNames.length() > 0 && (verbose || failureOccurred)) { @@ -355,22 +322,22 @@ public ActionReport runCommand( output.append(NL).append(Strings.get("cluster.command.instancesFailed", command, failedServerNames)); if (succeededServerNames.length() > 0) { // At least one instance started. Warning. - report.setActionExitCode(ExitCode.WARNING); + report.setActionExitCode(WARNING); } else { // No instance started. Failure - report.setActionExitCode(ExitCode.FAILURE); + report.setActionExitCode(FAILURE); } } // Check for server that did not respond if (!waitingForServerNames.isEmpty()) { - msg = Strings.get("cluster.command.instancesTimedOut", command, listToString(waitingForServerNames)); + String msg = Strings.get("cluster.command.instancesTimedOut", command, listToString(waitingForServerNames)); logger.warning(msg); if (output.length() > 0) { output.append(NL); } output.append(msg); - report.setActionExitCode(ExitCode.WARNING); + report.setActionExitCode(WARNING); } report.setMessage(output.toString()); @@ -382,24 +349,19 @@ public ActionReport runCommand( * Get the size of the admin threadpool */ private int getAdminThreadPoolSize() { - - final int DEFAULT_POOL_SIZE = 5; - // Get the DAS configuratoin Config config = domain.getConfigNamed("server-config"); - if (config == null) - return DEFAULT_POOL_SIZE; + if (config == null) { + return ADMIN_DEFAULT_POOL_SIZE; + } - AdminEndpointDecider aed = new AdminEndpointDecider(config); - return aed.getMaxThreadPoolSize(); + return new AdminEndpointDecider(config).getMaxThreadPoolSize(); } /** - * Optimize the order of the list of servers. Basically we - * want the server list to be ordered such that we rotate over - * the nodes. For example we want: n1, n2, n3, n1, n2, n3 - * not: n1, n1, n2, n2, n3, n3. This is to spread the load - * of operations across nodes. + * Optimize the order of the list of servers. Basically we want the server list to be ordered such that we rotate over + * the nodes. For example we want: n1, n2, n3, n1, n2, n3 not: n1, n1, n2, n2, n3, n3. This is to spread the load of + * operations across nodes. * * @param original a list of servers * @return a list of servers with a more optimal order @@ -417,8 +379,7 @@ public List optimizeServerListOrder(List original) { // create the final list. // Key is the node name, value is the list of servers on that node - HashMap> serverTable = - new HashMap>(); + HashMap> serverTable = new HashMap<>(); // Distribute servers into serverTable int count = 0; @@ -427,7 +388,7 @@ public List optimizeServerListOrder(List original) { List serverList = serverTable.get(nodeName); if (serverList == null) { - serverList = new ArrayList(); + serverList = new ArrayList<>(); serverTable.put(nodeName, serverList); } serverList.add(server); @@ -436,12 +397,12 @@ public List optimizeServerListOrder(List original) { // Now snake through server table moving server entries from the // table to the final optimized list. - List optimized = new ArrayList(count); + List optimized = new ArrayList<>(count); Set nodes = serverTable.keySet(); while (count > 0) { for (String nodeName : nodes) { List serverList = serverTable.get(nodeName); - if (! serverList.isEmpty()) { + if (!serverList.isEmpty()) { optimized.add(serverList.remove(0)); count--; } @@ -452,11 +413,15 @@ public List optimizeServerListOrder(List original) { } private static String serverListToString(List servers) { - StringBuilder sb = new StringBuilder(); - for (Server s : servers) { - sb.append(s.getNodeRef()).append(":").append(s.getName()).append(" "); + StringBuilder serverListBuilder = new StringBuilder(); + for (Server server : servers) { + serverListBuilder.append(server.getNodeRef()) + .append(":") + .append(server.getName()) + .append(" "); } - return sb.toString().trim(); + + return serverListBuilder.toString().trim(); } private static String listToString(List slist) { @@ -468,7 +433,7 @@ private static String listToString(List slist) { } public static class ReportResult { - public final List succeededServerNames = new ArrayList(); - public final List failedServerNames = new ArrayList(); + public final List succeededServerNames = new ArrayList<>(); + public final List failedServerNames = new ArrayList<>(); } } diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CommandRunnable.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CommandRunnable.java index 8fee0cff229..febcb77c872 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CommandRunnable.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CommandRunnable.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ - +// Portions Copyright [2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.v3.admin.cluster; import java.util.concurrent.BlockingQueue; @@ -46,69 +46,59 @@ import org.glassfish.api.admin.CommandRunner.CommandInvocation; /** - * This class wraps a CommandInvocation so that it can be run via a - * thread pool. On construction you pass it the CommandInvocation - * to execute as well as a response queue and the ActionReport - * that was set on the CommandInvocation. When the run() method - * is called the CommandInvocation is executed (which sets its results - * in the ActionReport) and then it adds itself to the response queue - * where it can be picked up and the ActionReport inspected for the results. + * This class wraps a CommandInvocation so that it can be run via a thread pool. On construction you pass it the + * CommandInvocation to execute as well as a response queue and the ActionReport that was set on the CommandInvocation. + * When the run() method is called the CommandInvocation is executed (which sets its results in the ActionReport) and + * then it adds itself to the response queue where it can be picked up and the ActionReport inspected for the results. * * @author dipol */ public class CommandRunnable implements Runnable { - BlockingQueue responseQueue = null; - String name = ""; - CommandInvocation ci = null; - ActionReport report = null; - - private CommandRunnable() { - } + private BlockingQueue responseQueue; + private String name = ""; + private CommandInvocation commandInvocation; + private ActionReport report; /** - * Construct a CommandRunnable. This class wraps a CommandInvocation - * so that it can be executed via a thread pool. + * Construct a CommandRunnable. This class wraps a CommandInvocation so that it can be executed via a thread pool. * - * @param ci A CommandInvocation containing the command you want - * to run. - * @param report The ActionReport you used with the CommandInvocation - * @param q A blocking queue that this class will add itself to - * when its run method has completed. + * @param commandInvocation A CommandInvocation containing the command you want to run. + * @param report The ActionReport you used with the CommandInvocation + * @param responseQueue A blocking queue that this class will add itself to when its run method has completed. * - * After dispatching this class to a thread pool the caller can block - * on the response queue where it will dequeue CommandRunnables and then - * use the getActionReport() method to retrieve the results. + * After dispatching this class to a thread pool the caller can block on the response queue where it will dequeue + * CommandRunnables and then use the getActionReport() method to retrieve the results. */ - public CommandRunnable(CommandInvocation ci, ActionReport report, - BlockingQueue q) { - this.responseQueue = q; + public CommandRunnable(CommandInvocation commandInvocation, ActionReport report, BlockingQueue responseQueue) { + this.commandInvocation = commandInvocation; this.report = report; - this.ci = ci; + this.responseQueue = responseQueue; } @Override public void run() { - ci.execute(); + commandInvocation.execute(); + if (responseQueue != null) { responseQueue.add(this); } } /** - * Set a name on the runnable. The name is not interpreted to mean - * anything so the caller can use it for whatever it likes. + * Set a name on the runnable. The name is not interpreted to mean anything so the caller can use it for whatever it + * likes. * - * @param s The name + * @param name The name */ - public void setName(String s) { - this.name = s; + public void setName(String name) { + this.name = name; } /** * Get the name that was previously set. * - * @return A name that was previously set or null if no name was set. + * @return A name that was previously set or null if no name was set. */ public String getName() { return name; @@ -117,16 +107,16 @@ public String getName() { /** * Returns the CommandInvocation that was passed on the constructor * - * @return The CommandInvocation that was passed on the constructor + * @return The CommandInvocation that was passed on the constructor */ public CommandInvocation getCommandInvocation() { - return ci; + return commandInvocation; } /** * Returns the ActionReport that was passed on the constructor. * - * @return the ActionReport that was passed on the constructor. + * @return the ActionReport that was passed on the constructor. */ public ActionReport getActionReport() { return report; @@ -136,8 +126,8 @@ public ActionReport getActionReport() { public String toString() { if (name == null) { return "null"; - } else { - return name; } + + return name; } } diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/Constants.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/Constants.java index e42f54eb56d..6b654ceea44 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/Constants.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/Constants.java @@ -37,11 +37,12 @@ * only if the new code is made subject to such option by the copyright * holder. */ - +// Portions Copyright [2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.v3.admin.cluster; /** * Only accessible inside this package. + * * @author bnevins */ class Constants { diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CopyConfigCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CopyConfigCommand.java index f3d63100fec..99498244c4f 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CopyConfigCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CopyConfigCommand.java @@ -37,28 +37,33 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.v3.admin.cluster; -import com.sun.enterprise.config.serverbeans.*; -import com.sun.enterprise.util.LocalStringManagerImpl; +import static org.glassfish.api.ActionReport.ExitCode.FAILURE; +import static org.glassfish.api.ActionReport.ExitCode.SUCCESS; +import static org.glassfish.api.admin.RestEndpoint.OpType.POST; + +import java.beans.PropertyVetoException; +import java.util.logging.Logger; + import org.glassfish.api.ActionReport; import org.glassfish.api.I18n; import org.glassfish.api.admin.AdminCommandContext; - -import org.jvnet.hk2.annotations.Service; +import org.glassfish.api.admin.RestEndpoint; +import org.glassfish.api.admin.RestEndpoints; import org.glassfish.hk2.api.PerLookup; +import org.jvnet.hk2.annotations.Service; import org.jvnet.hk2.config.ConfigSupport; import org.jvnet.hk2.config.SingleConfigCode; import org.jvnet.hk2.config.TransactionFailure; -import java.beans.PropertyVetoException; -import java.util.logging.Logger; -import org.glassfish.api.admin.RestEndpoint; -import org.glassfish.api.admin.RestEndpoint.OpType; -import org.glassfish.api.admin.RestEndpoints; +import com.sun.enterprise.config.serverbeans.Config; +import com.sun.enterprise.config.serverbeans.Configs; +import com.sun.enterprise.config.serverbeans.CopyConfig; +import com.sun.enterprise.util.LocalStringManagerImpl; /** * This is a remote command that copies a config to a destination config. @@ -70,9 +75,8 @@ @Service(name = "copy-config") @I18n("copy.config.command") @PerLookup -// {"Configs", "copy-config", "POST", "copy-config", "Copy Config"}, @RestEndpoints({ - @RestEndpoint(configBean=Configs.class, opType=OpType.POST, path="copy-config", description="Copy Config") + @RestEndpoint(configBean = Configs.class, opType = POST, path = "copy-config", description = "Copy Config") }) public final class CopyConfigCommand extends CopyConfig { @@ -81,55 +85,48 @@ public final class CopyConfigCommand extends CopyConfig { @Override public void execute(AdminCommandContext context) { ActionReport report = context.getActionReport(); - report.setActionExitCode(ActionReport.ExitCode.SUCCESS); + report.setActionExitCode(SUCCESS); if (configs.size() != 2) { - report.setMessage(localStrings.getLocalString("Config.badConfigNames", - "You must specify a source and destination config.")); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setMessage(localStrings.getLocalString("Config.badConfigNames", "You must specify a source and destination config.")); + report.setActionExitCode(FAILURE); return; } - final String srcConfig = configs.get(0); - final String destConfig = configs.get(1); - //Get the config from the domain - //does the src config exist - final Config config = domain.getConfigNamed(srcConfig); - if (config == null ){ - report.setMessage(localStrings.getLocalString( - "Config.noSuchConfig", "Config {0} does not exist.", srcConfig)); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + String srcConfig = configs.get(0); + String destConfig = configs.get(1); + + // Get the config from the domain + // Does the src config exist + Config config = domain.getConfigNamed(srcConfig); + if (config == null) { + report.setMessage(localStrings.getLocalString("Config.noSuchConfig", "Config {0} does not exist.", srcConfig)); + report.setActionExitCode(FAILURE); return; } - //does dest config exist - final Config destinationConfig = domain.getConfigNamed(destConfig); - if (destinationConfig != null ){ - report.setMessage(localStrings.getLocalString( - "Config.configExists", "Config {0} already exists.", destConfig)); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + // Does dest config exist + Config destinationConfig = domain.getConfigNamed(destConfig); + if (destinationConfig != null) { + report.setMessage(localStrings.getLocalString("Config.configExists", "Config {0} already exists.", destConfig)); + report.setActionExitCode(FAILURE); return; } - //Copy the config - final String configName = destConfig ; - final Logger logger = context.getLogger(); + // Copy the config + String configName = destConfig; + Logger logger = context.getLogger(); try { - ConfigSupport.apply(new SingleConfigCode(){ + ConfigSupport.apply(new SingleConfigCode() { @Override - public Object run(Configs configs ) throws PropertyVetoException, TransactionFailure { - return copyConfig(configs,config,configName,logger); + public Object run(Configs configs) throws PropertyVetoException, TransactionFailure { + return copyConfig(configs, config, configName, logger); } - } ,domain.getConfigs()); - + }, domain.getConfigs()); } catch (TransactionFailure e) { - report.setMessage( - localStrings.getLocalString( - "Config.copyConfigError", - "CopyConfig error caused by " , - e.getLocalizedMessage())); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setMessage(localStrings.getLocalString("Config.copyConfigError", "CopyConfig error caused by ", e.getLocalizedMessage())); + report.setActionExitCode(FAILURE); report.setFailureCause(e); } } diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateInstanceCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateInstanceCommand.java index c41606725a1..0be62502a56 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateInstanceCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateInstanceCommand.java @@ -37,37 +37,53 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] Payara Foundation and/or its affiliates] package com.sun.enterprise.v3.admin.cluster; -import com.sun.enterprise.config.serverbeans.*; -import com.sun.enterprise.universal.glassfish.ASenvPropertyReader; -import com.sun.enterprise.util.SystemPropertyConstants; -import com.sun.enterprise.util.StringUtils; -import com.sun.enterprise.util.ExceptionUtil; -import java.io.IOException; -import org.glassfish.api.ActionReport; -import com.sun.enterprise.util.io.InstanceDirs; +import static com.sun.enterprise.util.SystemPropertyConstants.AGENT_ROOT_PROPERTY; +import static java.util.logging.Level.SEVERE; +import static org.glassfish.api.ActionReport.ExitCode.FAILURE; +import static org.glassfish.api.ActionReport.ExitCode.SUCCESS; +import static org.glassfish.api.ActionReport.ExitCode.WARNING; +import static org.glassfish.api.admin.RestEndpoint.OpType.POST; + import java.io.File; +import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.inject.Inject; + +import org.glassfish.api.ActionReport; import org.glassfish.api.I18n; import org.glassfish.api.Param; -import org.glassfish.api.admin.*; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.CommandRunner; import org.glassfish.api.admin.CommandRunner.CommandInvocation; -import org.glassfish.hk2.api.IterableProvider; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.ParameterMap; +import org.glassfish.api.admin.RestEndpoint; +import org.glassfish.api.admin.RestEndpoints; +import org.glassfish.api.admin.RuntimeType; +import org.glassfish.api.admin.ServerEnvironment; import org.glassfish.hk2.api.PerLookup; import org.glassfish.hk2.api.ServiceLocator; -import org.glassfish.internal.api.ServerContext; - import org.jvnet.hk2.annotations.Service; -import java.util.logging.Logger; -import javax.inject.Inject; + +import com.sun.enterprise.config.serverbeans.Domain; +import com.sun.enterprise.config.serverbeans.Node; +import com.sun.enterprise.config.serverbeans.Nodes; +import com.sun.enterprise.config.serverbeans.Server; +import com.sun.enterprise.config.serverbeans.Servers; +import com.sun.enterprise.universal.glassfish.ASenvPropertyReader; +import com.sun.enterprise.util.ExceptionUtil; +import com.sun.enterprise.util.StringUtils; +import com.sun.enterprise.util.SystemPropertyConstants; +import com.sun.enterprise.util.io.InstanceDirs; /** * Remote AdminCommand to create an instance. This command is run only on DAS. @@ -80,58 +96,69 @@ @Service(name = "create-instance") @I18n("create.instance") @PerLookup -@ExecuteOn({RuntimeType.DAS}) +@ExecuteOn(RuntimeType.DAS) @RestEndpoints({ @RestEndpoint(configBean=Domain.class, - opType=RestEndpoint.OpType.POST, + opType=POST, path="create-instance", description="Create Instance") }) public class CreateInstanceCommand implements AdminCommand { private static final String NEWLINE = System.lineSeparator(); - @Inject - private CommandRunner cr; - @Inject - ServiceLocator habitat; - @Inject - IterableProvider nodeList; - @Inject - private Nodes nodes; - @Inject - private Servers servers; - @Inject - private ServerEnvironment env; - @Inject - private ServerContext serverContext; @Param(name = "node", alias = "nodeagent") String node; + @Param(name = "config", optional = true) @I18n("generic.config") String configRef; + @Param(name = "cluster", optional = true) String clusterName; + @Param(name = "deploymentgroup", optional = true) String deploymentGroup; + @Param(name = "lbenabled", optional = true) private Boolean lbEnabled; + @Param(name = "checkports", optional = true, defaultValue = "true") private boolean checkPorts; + @Param(optional = true, defaultValue = "false") private boolean terse; + @Param(name = "portbase", optional = true) private String portBase; + @Param(name = "systemproperties", optional = true, separator = ':') private String systemProperties; + @Param(name = "instance_name", primary = true) private String instance; - private Logger logger = null; // set in execute and all references occur after that assignment + + @Inject + private CommandRunner commandRunner; + + @Inject + private ServiceLocator serviceLocator; + + @Inject + private Nodes nodes; + + @Inject + private Servers servers; + + @Inject + private ServerEnvironment env; + + private Logger logger; // set in execute and all references occur after that assignment private AdminCommandContext ctx; - private Node theNode = null; - private String nodeHost = null; - private String nodeDir = null; - private String installDir = null; - private String registerInstanceMessage = null; + private Node theNode; + private String nodeHost; + private String nodeDir; + private String installDir; + private String registerInstanceMessage; @Override public void execute(AdminCommandContext context) { @@ -142,7 +169,7 @@ public void execute(AdminCommandContext context) { if (!env.isDas()) { String msg = Strings.get("notAllowed"); logger.warning(msg); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); return; } @@ -152,7 +179,7 @@ public void execute(AdminCommandContext context) { if (theNode == null) { String msg = Strings.get("noSuchNode", node); logger.warning(msg); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); return; } @@ -160,7 +187,7 @@ public void execute(AdminCommandContext context) { if (lbEnabled != null && clusterName == null) { String msg = Strings.get("lbenabledNotForStandaloneInstance"); logger.warning(msg); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); return; } @@ -169,66 +196,62 @@ public void execute(AdminCommandContext context) { nodeDir = theNode.getNodeDirAbsolute(); installDir = theNode.getInstallDir(); - if (theNode.isLocal()){ + if (theNode.isLocal()) { validateInstanceDirUnique(report, context); - if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS - && report.getActionExitCode() != ActionReport.ExitCode.WARNING) { + if (report.getActionExitCode() != SUCCESS && report.getActionExitCode() != WARNING) { // If we couldn't update domain.xml then stop! return; } } - + // First, update domain.xml by calling _register-instance - CommandInvocation ci = cr.getCommandInvocation("_register-instance", report, context.getSubject()); - ParameterMap map = new ParameterMap(); - map.add("node", node); - map.add("config", configRef); - map.add("cluster", clusterName); - map.add("deploymentgroup", deploymentGroup); + CommandInvocation commandInvocation = commandRunner.getCommandInvocation("_register-instance", report, context.getSubject()); + ParameterMap commandParameters = new ParameterMap(); + commandParameters.add("node", node); + commandParameters.add("config", configRef); + commandParameters.add("cluster", clusterName); + commandParameters.add("deploymentgroup", deploymentGroup); if (lbEnabled != null) { - map.add("lbenabled", lbEnabled.toString()); + commandParameters.add("lbenabled", lbEnabled.toString()); } if (!checkPorts) { - map.add("checkports", "false"); + commandParameters.add("checkports", "false"); } if (StringUtils.ok(portBase)) { - map.add("portbase", portBase); + commandParameters.add("portbase", portBase); } - map.add("systemproperties", systemProperties); - map.add("DEFAULT", instance); - ci.parameters(map); - ci.execute(); - + commandParameters.add("systemproperties", systemProperties); + commandParameters.add("DEFAULT", instance); + commandInvocation.parameters(commandParameters); + + commandInvocation.execute(); - if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS - && report.getActionExitCode() != ActionReport.ExitCode.WARNING) { + if (report.getActionExitCode() != SUCCESS && report.getActionExitCode() != WARNING) { // If we couldn't update domain.xml then stop! return; } registerInstanceMessage = report.getMessage(); - // if nodehost is localhost and installdir is null and config node, update config node + // If nodehost is localhost and installdir is null and config node, update config node // so installdir is product root. see register-instance above if (theNode.isLocal() && installDir == null) { - ci = cr.getCommandInvocation("_update-node", report, context.getSubject()); - map = new ParameterMap(); - map.add("installdir", "${com.sun.aas.productRoot}"); - map.add("type", "CONFIG"); - map.add("DEFAULT", theNode.getName()); - ci.parameters(map); - ci.execute(); - - - if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS - && report.getActionExitCode() != ActionReport.ExitCode.WARNING) { + commandInvocation = commandRunner.getCommandInvocation("_update-node", report, context.getSubject()); + commandParameters = new ParameterMap(); + commandParameters.add("installdir", "${com.sun.aas.productRoot}"); + commandParameters.add("type", "CONFIG"); + commandParameters.add("DEFAULT", theNode.getName()); + commandInvocation.parameters(commandParameters); + commandInvocation.execute(); + + if (report.getActionExitCode() != SUCCESS && report.getActionExitCode() != WARNING) { // If we couldn't update domain.xml then stop! return; } } if (!validateDasOptions()) { - report.setActionExitCode(ActionReport.ExitCode.WARNING); + report.setActionExitCode(WARNING); return; } @@ -237,69 +260,62 @@ public void execute(AdminCommandContext context) { } private void validateInstanceDirUnique(ActionReport report, AdminCommandContext context) { - CommandInvocation listInstances = cr.getCommandInvocation("list-instances", report, context.getSubject()); - ParameterMap map = new ParameterMap(); - map.add("whichTarget", theNode.getName()); - listInstances.parameters(map); - listInstances.execute(); - Properties pro = listInstances.report().getExtraProperties(); - if (pro != null){ - List instanceList = (List) pro.get("instanceList"); - if (instanceList == null) + CommandInvocation listInstancesCommand = commandRunner.getCommandInvocation("list-instances", report, context.getSubject()); + ParameterMap commandParameters = new ParameterMap(); + commandParameters.add("whichTarget", theNode.getName()); + listInstancesCommand.parameters(commandParameters); + listInstancesCommand.execute(); + + Properties extraProperties = listInstancesCommand.report().getExtraProperties(); + if (extraProperties != null) { + List> instanceList = (List>) extraProperties.get("instanceList"); + if (instanceList == null) { return; - for (HashMap instanceMap : instanceList) { - final File nodeDirFile = (nodeDir != null - ? new File(nodeDir) - : defaultLocalNodeDirFile()); + } + + for (Map instanceMap : instanceList) { + File nodeDirFile = nodeDir != null ? new File(nodeDir) : defaultLocalNodeDirFile(); File instanceDir = new File(new File(nodeDirFile.toString(), theNode.getName()), instance); - String instanceName = (String)instanceMap.get("name"); + String instanceName = instanceMap.get("name"); File instanceListDir = new File(new File(nodeDirFile.toString(), theNode.getName()), instance); + if (instance.equalsIgnoreCase(instanceName) && instanceDir.equals(instanceListDir)) { String msg = Strings.get("Instance.duplicateInstanceDir", instance, instanceName); logger.warning(msg); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); + return; } } } } - + /** - * Returns the directory for the selected instance that is on the local - * system. + * Returns the directory for the selected instance that is on the local system. + * * @param instanceName name of the instance * @return File for the local file system location of the instance directory * @throws IOException */ private File getLocalInstanceDir() throws IOException { /* - * Pass the node directory parent and the node directory name explicitly - * or else InstanceDirs will not work as we want if there are multiple - * nodes registered on this node. + * Pass the node directory parent and the node directory name explicitly or else InstanceDirs will not work as we want + * if there are multiple nodes registered on this node. * - * If the configuration recorded an explicit directory for the node, - * then use it. Otherwise, use the default node directory of - * ${installDir}/glassfish/nodes/${nodeName}. + * If the configuration recorded an explicit directory for the node, then use it. Otherwise, use the default node + * directory of ${installDir}/glassfish/nodes/${nodeName}. */ - final File nodeDirFile = (nodeDir != null - ? new File(nodeDir) - : defaultLocalNodeDirFile()); - InstanceDirs instanceDirs = new InstanceDirs(nodeDirFile.toString(), theNode.getName(), instance); - return instanceDirs.getInstanceDir(); + File nodeDirFile = nodeDir != null ? new File(nodeDir) : defaultLocalNodeDirFile(); + + return new InstanceDirs(nodeDirFile.toString(), theNode.getName(), instance).getInstanceDir(); } private File defaultLocalNodeDirFile() { - final Map systemProps = - Collections.unmodifiableMap(new ASenvPropertyReader().getProps()); /* - * The default "nodes" directory we want to use - * has been set in asenv.conf named as - * AS_DEF_NODES_PATH + * The default "nodes" directory we want to use has been set in asenv.conf named as AS_DEF_NODES_PATH */ - String nodeDirDefault = systemProps.get( - SystemPropertyConstants.AGENT_ROOT_PROPERTY); - return new File(nodeDirDefault); + return new File(new ASenvPropertyReader().getProps().get(AGENT_ROOT_PROPERTY)); } @@ -309,96 +325,83 @@ private File getDomainInstanceDir() { /** * - * Delivers bootstrap files for secure admin locally, because the instance - * is on the same system as the DAS (and therefore on the same system where - * this command is running). + * Delivers bootstrap files for secure admin locally, because the instance is on the same system as the DAS (and + * therefore on the same system where this command is running). * * @return 0 if successful, 1 otherwise */ private int bootstrapSecureAdminLocally() { - final ActionReport report = ctx.getActionReport(); + ActionReport report = ctx.getActionReport(); try { - final SecureAdminBootstrapHelper bootHelper = - SecureAdminBootstrapHelper.getLocalHelper( - env.getInstanceRoot(), - getLocalInstanceDir()); + SecureAdminBootstrapHelper bootHelper = SecureAdminBootstrapHelper.getLocalHelper(env.getInstanceRoot(), getLocalInstanceDir()); bootHelper.bootstrapInstance(); bootHelper.close(); + return 0; } catch (IOException | SecureAdminBootstrapHelper.BootstrapException ex) { return reportFailure(ex, report); } } - + private int reportFailure(final Exception ex, final ActionReport report) { String msg = Strings.get("create.instance.local.boot.failed", instance, node, nodeHost); - logger.log(Level.SEVERE, msg, ex); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + logger.log(SEVERE, msg, ex); + report.setActionExitCode(FAILURE); report.setMessage(msg); + return 1; } /** - * Delivers bootstrap files for secure admin remotely, because the instance - * is NOT on the same system as the DAS. + * Delivers bootstrap files for secure admin remotely, because the instance is NOT on the same system as the DAS. * * @return 0 if successful; 1 otherwise */ private int bootstrapSecureAdminRemotely() { ActionReport report = ctx.getActionReport(); + // nodedir is the root of where all the node dirs will be created. // add the name of the node as that is where the instance files should be created String thisNodeDir = null; - if (nodeDir != null) + if (nodeDir != null) { thisNodeDir = nodeDir + "/" + node; + } + try { - final SecureAdminBootstrapHelper bootHelper = - SecureAdminBootstrapHelper.getRemoteHelper( - habitat, - getDomainInstanceDir(), - thisNodeDir, - instance, + SecureAdminBootstrapHelper bootHelper = SecureAdminBootstrapHelper.getRemoteHelper(serviceLocator, getDomainInstanceDir(), thisNodeDir, instance, theNode, logger); bootHelper.bootstrapInstance(); bootHelper.close(); + return 0; - } - catch (Exception ex) { + } catch (Exception ex) { String exmsg = ex.getMessage(); if (exmsg == null) { // The root cause message is better than no message at all exmsg = ExceptionUtil.getRootCause(ex).toString(); } - String msg = Strings.get( - "create.instance.remote.boot.failed", - instance, - - + String msg = Strings.get("create.instance.remote.boot.failed", instance, // DCOMFIX - (ex instanceof SecureAdminBootstrapHelper.BootstrapException - ? ((SecureAdminBootstrapHelper.BootstrapException) ex).sshSettings() : null), + (ex instanceof SecureAdminBootstrapHelper.BootstrapException ? ((SecureAdminBootstrapHelper.BootstrapException) ex).sshSettings() : null), exmsg, - - - nodeHost); - logger.log(Level.SEVERE, msg, ex); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + logger.log(SEVERE, msg, ex); + report.setActionExitCode(FAILURE); report.setMessage(msg); + return 1; } } private void createInstanceFilesystem() { ActionReport report = ctx.getActionReport(); - report.setActionExitCode(ActionReport.ExitCode.SUCCESS); + report.setActionExitCode(SUCCESS); - NodeUtils nodeUtils = new NodeUtils(habitat, logger); - Server dasServer = - servers.getServer(SystemPropertyConstants.DAS_SERVER_NAME); + NodeUtils nodeUtils = new NodeUtils(serviceLocator, logger); + Server dasServer = servers.getServer(SystemPropertyConstants.DAS_SERVER_NAME); String dasHost = dasServer.getAdminHost(); String dasPort = Integer.toString(dasServer.getAdminPort()); @@ -428,71 +431,65 @@ private void createInstanceFilesystem() { humanCommand = makeCommandHuman(command); if (userManagedNodeType()) { - String msg = Strings.get("create.instance.config", - instance, humanCommand); - msg = StringUtils.cat(NEWLINE, registerInstanceMessage, msg); - report.setMessage(msg); + report.setMessage( + StringUtils.cat(NEWLINE, registerInstanceMessage, Strings.get("create.instance.config", instance, humanCommand))); + return; } // First error message displayed if we fail - String firstErrorMessage = Strings.get("create.instance.filesystem.failed", - instance, node, nodeHost); - StringBuilder output = new StringBuilder(); // Run the command on the node and handle errors. - nodeUtils.runAdminCommandOnNode(theNode, command, ctx, firstErrorMessage, - humanCommand, output); + nodeUtils.runAdminCommandOnNode( + theNode, command, ctx, Strings.get("create.instance.filesystem.failed", instance, node, nodeHost), humanCommand, output); - if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS) { - // something went wrong with the nonlocal command don't continue but set status to warning + if (report.getActionExitCode() != SUCCESS) { + // Something went wrong with the nonlocal command don't continue but set status to warning // because config was updated correctly or we would not be here. - report.setActionExitCode(ActionReport.ExitCode.WARNING); + report.setActionExitCode(WARNING); + return; } // If it was successful say so and display the command output - String msg = Strings.get("create.instance.success", - instance, nodeHost); + String msg = Strings.get("create.instance.success", instance, nodeHost); if (!terse) { - msg = StringUtils.cat(NEWLINE, - output.toString().trim(), registerInstanceMessage, msg); + msg = StringUtils.cat(NEWLINE, output.toString().trim(), registerInstanceMessage, msg); } report.setMessage(msg); // Bootstrap secure admin files if (theNode.isLocal()) { bootstrapSecureAdminLocally(); - } - else { + } else { bootstrapSecureAdminRemotely(); } - if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS) { + + if (report.getActionExitCode() != SUCCESS) { // something went wrong with the nonlocal command don't continue but set status to warning // because config was updated correctly or we would not be here. - report.setActionExitCode(ActionReport.ExitCode.WARNING); + report.setActionExitCode(WARNING); } } /** - * This ensures we don't step on another domain's node files on a remote - * instance. See bug GLASSFISH-14985. + * This ensures we don't step on another domain's node files on a remote instance. See bug GLASSFISH-14985. */ private boolean validateDasOptions() { boolean isDasOptionsValid = true; + if (theNode.isLocal() || (!theNode.isLocal() && theNode.getType().equals("SSH"))) { ActionReport report = ctx.getActionReport(); - report.setActionExitCode(ActionReport.ExitCode.SUCCESS); + report.setActionExitCode(SUCCESS); - NodeUtils nodeUtils = new NodeUtils(habitat, logger); - Server dasServer = - servers.getServer(SystemPropertyConstants.DAS_SERVER_NAME); + NodeUtils nodeUtils = new NodeUtils(serviceLocator, logger); + Server dasServer = servers.getServer(SystemPropertyConstants.DAS_SERVER_NAME); String dasHost = dasServer.getAdminHost(); String dasPort = Integer.toString(dasServer.getAdminPort()); - ArrayList command = new ArrayList(); + ArrayList command = new ArrayList<>(); if (!theNode.isLocal()) { // Only specify the DAS host if the node is remote. See issue 13993 @@ -507,7 +504,7 @@ private boolean validateDasOptions() { if (nodeDir != null) { command.add("--nodedir"); - command.add(nodeDir); //XXX escape spaces? + command.add(nodeDir); // XXX escape spaces? } command.add("--node"); @@ -518,47 +515,50 @@ private boolean validateDasOptions() { // Run the command on the node nodeUtils.runAdminCommandOnNode(theNode, command, ctx, "", null, null); - if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS) { - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + if (report.getActionExitCode() != SUCCESS) { + report.setActionExitCode(FAILURE); isDasOptionsValid = false; } } + return isDasOptionsValid; } - private String makeCommandHuman(List command) { + private String makeCommandHuman(List commands) { StringBuilder fullCommand = new StringBuilder(); fullCommand.append("lib"); fullCommand.append(System.getProperty("file.separator")); fullCommand.append("nadmin "); - for (String s : command) { - if (s.equals("_create-instance-filesystem")) { + for (String command : commands) { + if (command.equals("_create-instance-filesystem")) { // We tell the user to run create-local-instance, not the // hidden command fullCommand.append(" "); fullCommand.append("create-local-instance"); - } - else { + } else { fullCommand.append(" "); - fullCommand.append(s); + fullCommand.append(command); } } return fullCommand.toString(); } - // verbose but very readable... + // Verbose but very readable... private boolean userManagedNodeType() { - if(theNode.isLocal()) + if (theNode.isLocal()) { return false; + } - if(theNode.getType().equals("SSH")) + if (theNode.getType().equals("SSH")) { return false; + } - if(theNode.getType().equals("DCOM")) + if (theNode.getType().equals("DCOM")) { return false; + } return true; } diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeConfigCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeConfigCommand.java index db6851de486..88b57b61543 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeConfigCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeConfigCommand.java @@ -37,94 +37,118 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.v3.admin.cluster; -import com.sun.enterprise.config.serverbeans.Nodes; +import static com.sun.enterprise.util.net.NetUtils.isThisHostLocal; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.LANDMARK_FILE; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_INSTALLDIR; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_NODEDIR; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_NODEHOST; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_TYPE; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.sanitizeReport; +import static org.glassfish.api.ActionReport.ExitCode.FAILURE; +import static org.glassfish.api.admin.RestEndpoint.OpType.POST; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; + import org.glassfish.api.ActionReport; -import com.sun.enterprise.universal.glassfish.TokenResolver; -import com.sun.enterprise.util.StringUtils; import org.glassfish.api.I18n; import org.glassfish.api.Param; -import org.glassfish.api.admin.*; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.CommandRunner; import org.glassfish.api.admin.CommandRunner.CommandInvocation; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.ParameterMap; +import org.glassfish.api.admin.RestEndpoint; +import org.glassfish.api.admin.RestEndpoints; +import org.glassfish.api.admin.RuntimeType; import org.glassfish.hk2.api.PerLookup; - import org.jvnet.hk2.annotations.Service; -import java.util.Map; -import java.util.HashMap; -import com.sun.enterprise.util.net.NetUtils; -import java.io.File; -import javax.inject.Inject; + +import com.sun.enterprise.config.serverbeans.Nodes; +import com.sun.enterprise.universal.glassfish.TokenResolver; +import com.sun.enterprise.util.StringUtils; /** - * Remote AdminCommand to create a config node. This command is run only on DAS. - * Register the config node on DAS + * Remote AdminCommand to create a config node. This command is run only on DAS. + * Register the config node on DAS * * @author Carla Mott */ @Service(name = "create-node-config") @I18n("create.node.config") @PerLookup -@ExecuteOn({RuntimeType.DAS}) +@ExecuteOn(RuntimeType.DAS) @RestEndpoints({ - @RestEndpoint(configBean=Nodes.class, - opType=RestEndpoint.OpType.POST, - path="create-node-config", - description="Create Node Config") + @RestEndpoint(configBean = Nodes.class, + opType = POST, + path = "create-node-config", + description = "Create Node Config") }) public class CreateNodeConfigCommand implements AdminCommand { - - @Inject - private CommandRunner cr; - - @Param(name="name", primary = true) + @Param(name = "name", primary = true) String name; - @Param(name="nodedir", optional= true) + @Param(name = "nodedir", optional = true) String nodedir; - @Param(name="nodehost", optional= true) + @Param(name = "nodehost", optional = true) String nodehost; - @Param(name = "installdir", optional= true) + @Param(name = "installdir", optional = true) String installdir; + + @Inject + private CommandRunner commandRunner; @Override public void execute(AdminCommandContext context) { ActionReport report = context.getActionReport(); - //validate installdir if passed and running on localhost - if (StringUtils.ok(nodehost) && NetUtils.isThisHostLocal(nodehost) && StringUtils.ok(installdir)) { + // Validate installdir if passed and running on localhost + if (StringUtils.ok(nodehost) && isThisHostLocal(nodehost) && StringUtils.ok(installdir)) { TokenResolver resolver = null; // Create a resolver that can replace system properties in strings Map systemPropsMap = new HashMap((Map) (System.getProperties())); resolver = new TokenResolver(systemPropsMap); String resolvedInstallDir = resolver.resolve(installdir); - File actualInstallDir = new File(resolvedInstallDir + File.separator + NodeUtils.LANDMARK_FILE); + File actualInstallDir = new File(resolvedInstallDir + File.separator + LANDMARK_FILE); if (!actualInstallDir.exists()) { report.setMessage(Strings.get("invalid.installdir", installdir)); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); + return; } } - CommandInvocation ci = cr.getCommandInvocation("_create-node", report, context.getSubject()); - ParameterMap map = new ParameterMap(); - map.add("DEFAULT", name); - if (StringUtils.ok(nodedir)) - map.add(NodeUtils.PARAM_NODEDIR, nodedir); - if (StringUtils.ok(installdir)) - map.add(NodeUtils.PARAM_INSTALLDIR, installdir); - if (StringUtils.ok(nodehost)) - map.add(NodeUtils.PARAM_NODEHOST, nodehost); - map.add(NodeUtils.PARAM_TYPE,"CONFIG"); - ci.parameters(map); - ci.execute(); - - NodeUtils.sanitizeReport(report); + + CommandInvocation commandInvocation = commandRunner.getCommandInvocation("_create-node", report, context.getSubject()); + ParameterMap commandParameters = new ParameterMap(); + + commandParameters.add("DEFAULT", name); + if (StringUtils.ok(nodedir)) { + commandParameters.add(PARAM_NODEDIR, nodedir); + } + if (StringUtils.ok(installdir)) { + commandParameters.add(PARAM_INSTALLDIR, installdir); + } + if (StringUtils.ok(nodehost)) { + commandParameters.add(PARAM_NODEHOST, nodehost); + } + commandParameters.add(PARAM_TYPE, "CONFIG"); + + commandInvocation.parameters(commandParameters); + commandInvocation.execute(); + + sanitizeReport(report); } } diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeImplicitCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeImplicitCommand.java index addecd62820..dafffc330ed 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeImplicitCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeImplicitCommand.java @@ -37,24 +37,36 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.v3.admin.cluster; -import com.sun.enterprise.config.serverbeans.Domain; -import com.sun.enterprise.config.serverbeans.Nodes; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_INSTALLDIR; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_NODEDIR; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_NODEHOST; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_TYPE; +import static org.glassfish.api.admin.RestEndpoint.OpType.POST; + +import javax.inject.Inject; + import org.glassfish.api.ActionReport; import org.glassfish.api.I18n; import org.glassfish.api.Param; -import org.glassfish.api.admin.*; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.CommandRunner; import org.glassfish.api.admin.CommandRunner.CommandInvocation; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.ParameterMap; +import org.glassfish.api.admin.RestEndpoint; +import org.glassfish.api.admin.RestEndpoints; +import org.glassfish.api.admin.RuntimeType; import org.glassfish.hk2.api.PerLookup; - -import javax.inject.Inject; - - import org.jvnet.hk2.annotations.Service; +import com.sun.enterprise.config.serverbeans.Domain; +import com.sun.enterprise.config.serverbeans.Nodes; + /** * Remote AdminCommand to create a config node. This command is run only on DAS. * Register the config node on DAS @@ -64,56 +76,56 @@ @Service(name = "_create-node-implicit") @I18n("create.node.implicit") @PerLookup -@ExecuteOn({RuntimeType.DAS}) +@ExecuteOn(RuntimeType.DAS) @RestEndpoints({ - @RestEndpoint(configBean=Domain.class, - opType=RestEndpoint.OpType.POST, - path="_create-node-implicit", - description="_create-node-implicit") + @RestEndpoint(configBean = Domain.class, + opType = POST, + path = "_create-node-implicit", + description = "_create-node-implicit") }) public class CreateNodeImplicitCommand implements AdminCommand { - @Inject - Nodes nodes; - - @Inject - private CommandRunner cr; - - @Param(name="name", optional= true) + @Param(name = "name", optional = true) String name; - @Param(name="nodedir", optional = true) + @Param(name = "nodedir", optional = true) String nodedir; - @Param(name="nodehost", primary = true) + @Param(name = "nodehost", primary = true) String nodehost; @Param(name = "installdir") String installdir; + + @Inject + private Nodes nodes; + + @Inject + private CommandRunner commandRunner; @Override public void execute(AdminCommandContext context) { ActionReport report = context.getActionReport(); - if (name == null) + if (name == null) { name = nodehost; + } if (nodes.getNode(name) != null) { - //already created nothing to do here + // Already created nothing to do here return; } - CommandInvocation ci = cr.getCommandInvocation("_create-node", report, context.getSubject()); - ParameterMap map = new ParameterMap(); - map.add("DEFAULT", name); - map.add(NodeUtils.PARAM_NODEDIR, nodedir); - map.add(NodeUtils.PARAM_INSTALLDIR, installdir); - map.add(NodeUtils.PARAM_NODEHOST, nodehost); - map.add(NodeUtils.PARAM_TYPE,"CONFIG"); - - ci.parameters(map); - ci.execute(); - + CommandInvocation commandInvocation = commandRunner.getCommandInvocation("_create-node", report, context.getSubject()); + ParameterMap commandParameters = new ParameterMap(); + commandParameters.add("DEFAULT", name); + commandParameters.add(PARAM_NODEDIR, nodedir); + commandParameters.add(PARAM_INSTALLDIR, installdir); + commandParameters.add(PARAM_NODEHOST, nodehost); + commandParameters.add(PARAM_TYPE, "CONFIG"); + + commandInvocation.parameters(commandParameters); + commandInvocation.execute(); } } diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeSshCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeSshCommand.java index 2000ff68df2..64ce6bf04b7 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeSshCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateNodeSshCommand.java @@ -37,24 +37,35 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.v3.admin.cluster; -import com.sun.enterprise.config.serverbeans.Nodes; -import java.util.List; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.NODE_DEFAULT_REMOTE_USER; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.NODE_DEFAULT_SSH_PORT; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_SSHKEYFILE; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_SSHKEYPASSPHRASE; +import static org.glassfish.api.admin.RestEndpoint.OpType.POST; +import static org.glassfish.cluster.ssh.util.SSHUtil.getExistingKeyFile; + import java.util.ArrayList; -import com.sun.enterprise.util.cluster.RemoteType; -import com.sun.enterprise.util.StringUtils; +import java.util.List; + import org.glassfish.api.I18n; import org.glassfish.api.Param; -import org.glassfish.api.admin.*; - - +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.CommandValidationException; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.ParameterMap; +import org.glassfish.api.admin.RestEndpoint; +import org.glassfish.api.admin.RestEndpoints; +import org.glassfish.api.admin.RuntimeType; +import org.glassfish.hk2.api.PerLookup; import org.jvnet.hk2.annotations.Service; -import org.glassfish.cluster.ssh.util.SSHUtil; -import org.glassfish.hk2.api.PerLookup; +import com.sun.enterprise.config.serverbeans.Nodes; +import com.sun.enterprise.util.StringUtils; +import com.sun.enterprise.util.cluster.RemoteType; /** * Remote AdminCommand to create and ssh node. This command is run only on DAS. @@ -65,22 +76,27 @@ @Service(name = "create-node-ssh") @I18n("create.node.ssh") @PerLookup -@ExecuteOn({RuntimeType.DAS}) +@ExecuteOn(RuntimeType.DAS) @RestEndpoints({ - @RestEndpoint(configBean=Nodes.class, - opType=RestEndpoint.OpType.POST, - path="create-node-ssh", - description="Create Node SSH") + @RestEndpoint(configBean = Nodes.class, + opType = POST, + path = "create-node-ssh", + description = "Create Node SSH") }) public class CreateNodeSshCommand extends CreateRemoteNodeCommand { - @Param(name = "sshport", optional = true, defaultValue = NodeUtils.NODE_DEFAULT_SSH_PORT) + + @Param(name = "sshport", optional = true, defaultValue = NODE_DEFAULT_SSH_PORT) private String sshport; - @Param(name = "sshuser", optional = true, defaultValue = NodeUtils.NODE_DEFAULT_REMOTE_USER) + + @Param(name = "sshuser", optional = true, defaultValue = NODE_DEFAULT_REMOTE_USER) private String sshuser; + @Param(name = "sshpassword", optional = true, password = true) private String sshpassword; + @Param(name = "sshkeyfile", optional = true) private String sshkeyfile; + @Param(name = "sshkeypassphrase", optional = true, password = true) private String sshkeypassphrase; @@ -101,15 +117,14 @@ protected void validate() throws CommandValidationException { } /** - * Sometimes the console passes an empty string for a parameter. This - * makes sure those are defaulted correctly. + * Sometimes the console passes an empty string for a parameter. This makes sure those are defaulted correctly. */ @Override protected final void checkDefaults() { super.checkDefaults(); if (!StringUtils.ok(remotePort)) { - remotePort = NodeUtils.NODE_DEFAULT_SSH_PORT; + remotePort = NODE_DEFAULT_SSH_PORT; } } @@ -119,8 +134,8 @@ protected final RemoteType getType() { } /** - * We can't put these values into the base class simply to get the names that - * the user sees correct. I.e. "ssh" versus "dcom" versus future types... + * We can't put these values into the base class simply to get the names that the user sees correct. I.e. "ssh" versus + * "dcom" versus future types... * */ @Override @@ -132,14 +147,14 @@ protected void populateBaseClass() { @Override protected final void populateParameters(ParameterMap pmap) { - pmap.add(NodeUtils.PARAM_SSHKEYFILE, sshkeyfile); - pmap.add(NodeUtils.PARAM_SSHKEYPASSPHRASE, sshkeypassphrase); + pmap.add(PARAM_SSHKEYFILE, sshkeyfile); + pmap.add(PARAM_SSHKEYPASSPHRASE, sshkeypassphrase); } @Override protected final void populateCommandArgs(List args) { if (sshkeyfile == null) { - sshkeyfile = SSHUtil.getExistingKeyFile(); + sshkeyfile = getExistingKeyFile(); } if (sshkeyfile != null) { @@ -155,18 +170,21 @@ protected final void populateCommandArgs(List args) { /** * Get list of password file entries + * * @return List */ @Override protected List getPasswords() { - List list = new ArrayList(); - NodeUtils nUtils = new NodeUtils(habitat, logger); - list.add("AS_ADMIN_SSHPASSWORD=" + nUtils.sshL.expandPasswordAlias(remotePassword)); + List passwords = new ArrayList(); + + NodeUtils nUtils = new NodeUtils(serviceLocator, logger); + passwords.add("AS_ADMIN_SSHPASSWORD=" + nUtils.sshL.expandPasswordAlias(remotePassword)); if (sshkeypassphrase != null) { - list.add("AS_ADMIN_SSHKEYPASSPHRASE=" + nUtils.sshL.expandPasswordAlias(sshkeypassphrase)); + passwords.add("AS_ADMIN_SSHKEYPASSPHRASE=" + nUtils.sshL.expandPasswordAlias(sshkeypassphrase)); } - return list; + + return passwords; } @Override diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateRemoteNodeCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateRemoteNodeCommand.java index 7b640b9c2f0..65639d3ff6b 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateRemoteNodeCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/CreateRemoteNodeCommand.java @@ -37,60 +37,92 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.v3.admin.cluster; -import com.sun.enterprise.util.cluster.RemoteType; -import com.sun.enterprise.universal.process.ProcessManager; -import com.sun.enterprise.universal.process.ProcessManagerException; -import com.sun.enterprise.util.SystemPropertyConstants; -import java.util.*; -import java.util.logging.*; -import java.io.*; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.NODE_DEFAULT_INSTALLDIR; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.NODE_DEFAULT_REMOTE_USER; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_INSTALL; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_INSTALLDIR; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_NODEDIR; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_NODEHOST; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_REMOTEPASSWORD; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_REMOTEPORT; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_REMOTEUSER; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_TYPE; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.sanitizeReport; +import static java.util.logging.Level.FINE; +import static java.util.logging.Level.FINER; +import static java.util.logging.Level.INFO; +import static org.glassfish.api.ActionReport.ExitCode.FAILURE; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import javax.inject.Inject; -import com.sun.enterprise.util.StringUtils; -import com.sun.enterprise.config.serverbeans.*; import org.glassfish.api.ActionReport; import org.glassfish.api.Param; -import org.glassfish.api.admin.*; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.CommandRunner; import org.glassfish.api.admin.CommandRunner.CommandInvocation; +import org.glassfish.api.admin.CommandValidationException; +import org.glassfish.api.admin.ParameterMap; import org.glassfish.hk2.api.ServiceLocator; -import javax.inject.Inject; +import com.sun.enterprise.config.serverbeans.Nodes; +import com.sun.enterprise.universal.process.ProcessManager; +import com.sun.enterprise.universal.process.ProcessManagerException; +import com.sun.enterprise.util.StringUtils; +import com.sun.enterprise.util.SystemPropertyConstants; +import com.sun.enterprise.util.cluster.RemoteType; /** - * Refactored from CreateNodeSshCommand.java on 9/10/11 - * Note the use of "protected" visibility is one of those rare times when it is actually - * necessary. This class is sub-classed in a different package so protected is needed... + * Refactored from CreateNodeSshCommand.java on 9/10/11 Note the use of "protected" visibility is one of those rare + * times when it is actually necessary. This class is sub-classed in a different package so protected is needed... + * * @author Carla Mott * @author Byron Nevins */ public abstract class CreateRemoteNodeCommand implements AdminCommand { static final int DEFAULT_TIMEOUT_MSEC = 300000; // 5 minutes - @Inject - private CommandRunner cr; - @Inject - ServiceLocator habitat; - @Inject - Nodes nodes; + static final String NL = System.lineSeparator(); + @Param(name = "name", primary = true) private String name; + @Param(name = "nodehost") protected String nodehost; - @Param(name = "installdir", optional = true, defaultValue = NodeUtils.NODE_DEFAULT_INSTALLDIR) + + @Param(name = "installdir", optional = true, defaultValue = NODE_DEFAULT_INSTALLDIR) private String installdir; + @Param(name = "nodedir", optional = true) private String nodedir; + @Param(name = "force", optional = true, defaultValue = "false") private boolean force; + @Param(optional = true, defaultValue = "false") boolean install; + @Param(optional = true) String archive; - static final String NL = System.lineSeparator(); - @SuppressWarnings("NonConstantLogger") - Logger logger = null; + + @Inject + private CommandRunner commandRunner; + + @Inject + ServiceLocator serviceLocator; + + @Inject + Nodes nodes; + + Logger logger; NodeUtils nodeUtils; protected String remotePort; protected String remoteUser; @@ -116,52 +148,48 @@ public final void executeInternal(AdminCommandContext context) { ActionReport report = context.getActionReport(); StringBuilder msg = new StringBuilder(); logger = context.getLogger(); + initialize(); populateBaseClass(); checkDefaults(); - ParameterMap map = new ParameterMap(); - populateParametersInternal(map); + ParameterMap commandParameters = new ParameterMap(); + populateParametersInternal(commandParameters); + try { validate(); - } - catch (CommandValidationException ex) { + } catch (CommandValidationException ex) { report.setMessage(ex.getLocalizedMessage()); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); return; } try { - nodeUtils = new NodeUtils(habitat, logger); - nodeUtils.validate(map); + nodeUtils = new NodeUtils(serviceLocator, logger); + nodeUtils.validate(commandParameters); if (install) { - boolean s = installNode(context); - if (!s && !force) { - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + if (!installNode(context) && !force) { + report.setActionExitCode(FAILURE); return; } } - } - catch (CommandValidationException e) { - String m1 = Strings.get("node.ssh.invalid.params"); + } catch (CommandValidationException e) { + String invalidParamsMsg = Strings.get("node.ssh.invalid.params"); if (!force) { - String m2 = Strings.get("create.node.ssh.or.dcom.not.created", getType().toString()); - msg.append(StringUtils.cat(NL, m1, m2, e.getMessage())); + msg.append(StringUtils.cat(NL, invalidParamsMsg, Strings.get("create.node.ssh.or.dcom.not.created", getType().toString()), e.getMessage())); report.setMessage(msg.toString()); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); return; - } - else { - String m2 = Strings.get("create.node.ssh.continue.force"); - msg.append(StringUtils.cat(NL, m1, e.getMessage(), m2)); + } else { + msg.append(StringUtils.cat(NL, invalidParamsMsg, e.getMessage(), Strings.get("create.node.ssh.continue.force"))); } } - map.remove(NodeUtils.PARAM_INSTALL); - CommandInvocation ci = cr.getCommandInvocation("_create-node", report, context.getSubject()); - ci.parameters(map); - ci.execute(); + commandParameters.remove(PARAM_INSTALL); + CommandInvocation commandInvocation = commandRunner.getCommandInvocation("_create-node", report, context.getSubject()); + commandInvocation.parameters(commandParameters); + commandInvocation.execute(); - NodeUtils.sanitizeReport(report); + sanitizeReport(report); if (StringUtils.ok(report.getMessage())) { if (msg.length() > 0) { @@ -173,29 +201,30 @@ public final void executeInternal(AdminCommandContext context) { report.setMessage(msg.toString()); } - private void populateParametersInternal(ParameterMap map) { - map.add("DEFAULT", name); - map.add(NodeUtils.PARAM_INSTALLDIR, installdir); - map.add(NodeUtils.PARAM_NODEHOST, nodehost); - map.add(NodeUtils.PARAM_NODEDIR, nodedir); - map.add(NodeUtils.PARAM_REMOTEPORT, remotePort); - map.add(NodeUtils.PARAM_REMOTEUSER, remoteUser); - map.add(NodeUtils.PARAM_REMOTEPASSWORD, remotePassword); - map.add(NodeUtils.PARAM_TYPE, getType().toString()); - map.add(NodeUtils.PARAM_INSTALL, Boolean.toString(install)); - - // let subclasses overwrite our values if they like. - populateParameters(map); + private void populateParametersInternal(ParameterMap parameters) { + parameters.add("DEFAULT", name); + parameters.add(PARAM_INSTALLDIR, installdir); + parameters.add(PARAM_NODEHOST, nodehost); + parameters.add(PARAM_NODEDIR, nodedir); + parameters.add(PARAM_REMOTEPORT, remotePort); + parameters.add(PARAM_REMOTEUSER, remoteUser); + parameters.add(PARAM_REMOTEPASSWORD, remotePassword); + parameters.add(PARAM_TYPE, getType().toString()); + parameters.add(PARAM_INSTALL, Boolean.toString(install)); + + // Let subclasses overwrite our values if they like. + populateParameters(parameters); } /** * Prepares for invoking install-node on DAS + * * @param ctx command context * @return true if install-node succeeds, false otherwise */ private boolean installNode(AdminCommandContext ctx) throws CommandValidationException { boolean res = false; - ArrayList command = new ArrayList(); + ArrayList command = new ArrayList<>(); command.add(getInstallNodeCommandName()); command.add("--installdir"); command.add(installdir); @@ -205,8 +234,8 @@ private boolean installNode(AdminCommandContext ctx) throws CommandValidationExc } if (archive != null) { - File ar = new File(archive); - if (ar.exists() && ar.canRead()) { + File archiveFile = new File(archive); + if (archiveFile.exists() && archiveFile.canRead()) { command.add("--archive"); command.add(archive); } @@ -218,37 +247,37 @@ private boolean installNode(AdminCommandContext ctx) throws CommandValidationExc StringBuilder out = new StringBuilder(); int exitCode = execCommand(command, out); - //capture the output in server.log + // capture the output in server.log logger.info(out.toString().trim()); ActionReport report = ctx.getActionReport(); if (exitCode == 0) { // If it was successful say so and display the command output - String msg = Strings.get("create.node.ssh.install.success", nodehost); - report.setMessage(msg); + report.setMessage(Strings.get("create.node.ssh.install.success", nodehost)); res = true; - } - else { + } else { report.setMessage(out.toString().trim()); } + return res; } /** - * Sometimes the console passes an empty string for a parameter. This - * makes sure those are defaulted correctly. + * Sometimes the console passes an empty string for a parameter. This makes sure those are defaulted correctly. */ protected void checkDefaults() { if (!StringUtils.ok(installdir)) { - installdir = NodeUtils.NODE_DEFAULT_INSTALLDIR; + installdir = NODE_DEFAULT_INSTALLDIR; } + if (!StringUtils.ok(remoteUser)) { - remoteUser = NodeUtils.NODE_DEFAULT_REMOTE_USER; + remoteUser = NODE_DEFAULT_REMOTE_USER; } } /** * Invokes install-node using ProcessManager and returns the exit message/status. + * * @param cmdLine list of args * @param output contains output message * @return exit status of install-node @@ -267,44 +296,45 @@ final int execCommand(List cmdLine, StringBuilder output) { File asadmin = new File(SystemPropertyConstants.getAsAdminScriptLocation(installDir)); fullcommand.add(asadmin.getAbsolutePath()); - //if password auth is used for creating node, use the same auth mechanism for - //install-node as well. The passwords are passed directly through input stream - List pass = new ArrayList(); + // if password auth is used for creating node, use the same auth mechanism for + // install-node as well. The passwords are passed directly through input stream + List passwords = new ArrayList(); if (remotePassword != null) { fullcommand.add("--passwordfile"); fullcommand.add("-"); - pass = getPasswords(); + passwords = getPasswords(); } fullcommand.add("--interactive=false"); fullcommand.addAll(cmdLine); - ProcessManager pm = new ProcessManager(fullcommand); - if (!pass.isEmpty()) - pm.setStdinLines(pass); + ProcessManager processManager = new ProcessManager(fullcommand); + if (!passwords.isEmpty()) + processManager.setStdinLines(passwords); - if (logger.isLoggable(Level.INFO)) { + if (logger.isLoggable(INFO)) { logger.info("Running command on DAS: " + commandListToString(fullcommand)); } - pm.setTimeoutMsec(DEFAULT_TIMEOUT_MSEC); + + processManager.setTimeoutMsec(DEFAULT_TIMEOUT_MSEC); - if (logger.isLoggable(Level.FINER)) - pm.setEcho(true); - else - pm.setEcho(false); + if (logger.isLoggable(FINER)) { + processManager.setEcho(true); + } else { + processManager.setEcho(false); + } try { - exit = pm.execute(); - } - catch (ProcessManagerException ex) { - if (logger.isLoggable(Level.FINE)) { + exit = processManager.execute(); + } catch (ProcessManagerException ex) { + if (logger.isLoggable(FINE)) { logger.fine("Error while executing command: " + ex.getMessage()); } exit = 1; } - String stdout = pm.getStdout(); - String stderr = pm.getStderr(); + String stdout = processManager.getStdout(); + String stderr = processManager.getStderr(); if (output != null) { if (StringUtils.ok(stdout)) { @@ -318,15 +348,16 @@ final int execCommand(List cmdLine, StringBuilder output) { output.append(stderr); } } + return exit; } - final String commandListToString(List command) { + final String commandListToString(List commands) { StringBuilder fullCommand = new StringBuilder(); - for (String s : command) { + for (String command : commands) { fullCommand.append(" "); - fullCommand.append(s); + fullCommand.append(command); } return fullCommand.toString(); diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteConfigCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteConfigCommand.java index e69216f8723..d5d689a6f67 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteConfigCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteConfigCommand.java @@ -37,27 +37,37 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.v3.admin.cluster; +import static org.glassfish.api.ActionReport.ExitCode.FAILURE; +import static org.glassfish.api.ActionReport.ExitCode.SUCCESS; + import java.beans.PropertyVetoException; import java.util.List; import javax.inject.Inject; - -import org.jvnet.hk2.annotations.Service; -import org.jvnet.hk2.config.*; -import org.glassfish.api.Param; import org.glassfish.api.ActionReport; import org.glassfish.api.I18n; -import org.glassfish.api.admin.*; +import org.glassfish.api.Param; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.RestEndpoint; +import org.glassfish.api.admin.RestEndpoints; +import org.glassfish.api.admin.RestParam; import org.glassfish.api.admin.config.ReferenceContainer; import org.glassfish.hk2.api.PerLookup; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.config.ConfigSupport; +import org.jvnet.hk2.config.SingleConfigCode; +import org.jvnet.hk2.config.TransactionFailure; +import com.sun.enterprise.config.serverbeans.Config; +import com.sun.enterprise.config.serverbeans.Configs; +import com.sun.enterprise.config.serverbeans.Domain; import com.sun.enterprise.util.LocalStringManagerImpl; -import com.sun.enterprise.config.serverbeans.*; /** * This is a remote command that deletes a destination config. @@ -70,87 +80,79 @@ @PerLookup @I18n("delete.config.command") @RestEndpoints({ - @RestEndpoint(configBean=Config.class, - opType=RestEndpoint.OpType.POST, // TODO: Should be DELETE - path="delete-config", - description="Delete Config", - params={ - @RestParam(name="id", value="$parent") - }) + @RestEndpoint(configBean = Config.class, + opType = RestEndpoint.OpType.POST, // TODO: Should be DELETE + path = "delete-config", + description = "Delete Config", + params = + @RestParam(name = "id", value = "$parent") + ) }) public final class DeleteConfigCommand implements AdminCommand { - @Param(primary=true) - String destConfig; + private final static LocalStringManagerImpl LOCAL_STRINGS = new LocalStringManagerImpl(DeleteConfigCommand.class); + + @Param(primary = true) + private String destConfig; @Inject - Configs configs; + private Configs configs; @Inject - Domain domain; - - - private final static LocalStringManagerImpl LOCAL_STRINGS = new LocalStringManagerImpl(DeleteConfigCommand.class); + private Domain domain; @Override public void execute(AdminCommandContext context) { ActionReport report = context.getActionReport(); - report.setActionExitCode(ActionReport.ExitCode.SUCCESS); - - //do not delete default-config - if (destConfig.equals("default-config") ){ - report.setMessage(LOCAL_STRINGS.getLocalString( - "Config.defaultConfig", "The default configuration template " + - "named default-config cannot be deleted." - )); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(SUCCESS); + + // Do not delete default-config + if (destConfig.equals("default-config")) { + report.setMessage( + LOCAL_STRINGS.getLocalString("Config.defaultConfig", "The default configuration template " + "named default-config cannot be deleted.")); + report.setActionExitCode(FAILURE); + return; } - //Get the config from the domain - //does the config exist ? - //if not return - final Config config = domain.getConfigNamed(destConfig); - if (config == null ){ - report.setMessage(LOCAL_STRINGS.getLocalString( - "Config.noSuchConfig", "Config {0} does not exist.", destConfig)); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + // Get the config from the domain. Does the config exist? + // if not return + Config config = domain.getConfigNamed(destConfig); + if (config == null) { + report.setMessage(LOCAL_STRINGS.getLocalString("Config.noSuchConfig", "Config {0} does not exist.", destConfig)); + report.setActionExitCode(FAILURE); + return; } - // check if the config in use by some other + // Check if the config in use by some other // ReferenceContainer -- if so just return... - List refContainers = domain.getReferenceContainersOf(config); - if(!refContainers.isEmpty()) { + List referenceContainers = domain.getReferenceContainersOf(config); + if (!referenceContainers.isEmpty()) { StringBuilder namesOfContainers = new StringBuilder(); - for (ReferenceContainer rc: refContainers) { - namesOfContainers.append(rc.getReference()).append(','); + for (ReferenceContainer referenceContainer : referenceContainers) { + namesOfContainers.append(referenceContainer.getReference()).append(','); } - report.setMessage(LOCAL_STRINGS.getLocalString( - "Config.inUseConfig", "Config {0} is in use " + - "and must be referenced by no server instances or clusters", - destConfig,namesOfContainers)); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setMessage(LOCAL_STRINGS.getLocalString("Config.inUseConfig", + "Config {0} is in use " + "and must be referenced by no server instances or clusters", destConfig, namesOfContainers)); + report.setActionExitCode(FAILURE); + return; - } + try { ConfigSupport.apply(new SingleConfigCode() { - @Override - public Object run(Configs c) throws PropertyVetoException, TransactionFailure { - List configList = c.getConfig(); - configList.remove(config); + public Object run(Configs configs) throws PropertyVetoException, TransactionFailure { + configs.getConfig().remove(config); return null; } }, configs); } catch (TransactionFailure ex) { report.setMessage( - LOCAL_STRINGS.getLocalString("Config.deleteConfigFailed", - "Unable to remove config {0} ", config) + " " - +ex.getLocalizedMessage()); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + LOCAL_STRINGS.getLocalString("Config.deleteConfigFailed", "Unable to remove config {0} ", config) + " " + ex.getLocalizedMessage()); + report.setActionExitCode(FAILURE); report.setFailureCause(ex); } diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteInstanceCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteInstanceCommand.java index 37f9e5a017b..33b30788b81 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteInstanceCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteInstanceCommand.java @@ -37,27 +37,42 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.v3.admin.cluster; -import com.sun.enterprise.config.serverbeans.*; -import com.sun.enterprise.util.StringUtils; +import static org.glassfish.api.ActionReport.ExitCode.FAILURE; +import static org.glassfish.api.ActionReport.ExitCode.SUCCESS; +import static org.glassfish.api.ActionReport.ExitCode.WARNING; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import javax.inject.Inject; + import org.glassfish.api.ActionReport; import org.glassfish.api.I18n; import org.glassfish.api.Param; -import org.glassfish.api.admin.*; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.CommandRunner; import org.glassfish.api.admin.CommandRunner.CommandInvocation; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.ParameterMap; +import org.glassfish.api.admin.RestEndpoint; +import org.glassfish.api.admin.RestEndpoints; +import org.glassfish.api.admin.RestParam; +import org.glassfish.api.admin.RuntimeType; import org.glassfish.hk2.api.PerLookup; import org.glassfish.hk2.api.ServiceLocator; - -import javax.inject.Inject; - - import org.jvnet.hk2.annotations.Service; -import java.util.logging.Logger; -import java.util.List; -import java.util.ArrayList; + +import com.sun.enterprise.config.serverbeans.Node; +import com.sun.enterprise.config.serverbeans.Nodes; +import com.sun.enterprise.config.serverbeans.Server; +import com.sun.enterprise.config.serverbeans.Servers; +import com.sun.enterprise.util.StringUtils; /** * Remote AdminCommand to delete an instance. This command is run only on DAS. @@ -80,12 +95,18 @@ public class DeleteInstanceCommand implements AdminCommand { private static final String NL = System.lineSeparator(); + + @Param(name = "instance_name", primary = true) + private String instanceName; + + @Param(defaultValue = "false", optional = true) + private boolean terse; @Inject - private CommandRunner cr; + private CommandRunner commandRunner; @Inject - ServiceLocator habitat; + private ServiceLocator serviceLocator; @Inject private Servers servers; @@ -93,27 +114,20 @@ public class DeleteInstanceCommand implements AdminCommand { @Inject private Nodes nodes; - @Param(name = "instance_name", primary = true) - private String instanceName; - - @Param(defaultValue = "false", optional=true) - private boolean terse; - private Server instance; private String noderef; private String nodedir; - @SuppressWarnings("NonConstantLogger") - private Logger logger; + private Logger logger; private String instanceHost; - private Node theNode = null; + private Node theNode; @Override public void execute(AdminCommandContext ctx) { ActionReport report = ctx.getActionReport(); logger = ctx.getLogger(); String msg = ""; - boolean fsfailure = false; - boolean configfailure = false; + boolean fsfailure = false; + boolean configfailure = false; // We are going to delete a server instance. Get the instance instance = servers.getServer(instanceName); @@ -121,18 +135,21 @@ public void execute(AdminCommandContext ctx) { if (instance == null) { msg = Strings.get("start.instance.noSuchInstance", instanceName); logger.warning(msg); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); + return; } + instanceHost = instance.getAdminHost(); // make sure instance is not running. - if (instance.isRunning()){ + if (instance.isRunning()) { msg = Strings.get("instance.shutdown", instanceName); logger.warning(msg); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); + return; } @@ -142,7 +159,7 @@ public void execute(AdminCommandContext ctx) { // Get the name of the node from the instance's node-ref field noderef = instance.getNodeRef(); - if(!StringUtils.ok(noderef)) { + if (!StringUtils.ok(noderef)) { msg = Strings.get("missingNodeRef", instanceName); fsfailure = true; } else { @@ -157,21 +174,20 @@ public void execute(AdminCommandContext ctx) { nodedir = theNode.getNodeDirAbsolute(); deleteInstanceFilesystem(ctx); report = ctx.getActionReport(); - if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS) { + if (report.getActionExitCode() != SUCCESS) { fsfailure = true; } msg = report.getMessage(); } // Now remove the instance from domain.xml. - CommandInvocation ci = cr.getCommandInvocation("_unregister-instance", report, ctx.getSubject()); - ParameterMap map = new ParameterMap(); - map.add("DEFAULT", instanceName); - ci.parameters(map); - ci.execute(); - - if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS && - report.getActionExitCode() != ActionReport.ExitCode.WARNING) { + CommandInvocation commandInvocation = commandRunner.getCommandInvocation("_unregister-instance", report, ctx.getSubject()); + ParameterMap commandParameters = new ParameterMap(); + commandParameters.add("DEFAULT", instanceName); + commandInvocation.parameters(commandParameters); + commandInvocation.execute(); + + if (report.getActionExitCode() != SUCCESS && report.getActionExitCode() != WARNING) { // Failed to delete from domain.xml configfailure = true; if (fsfailure) { @@ -184,33 +200,29 @@ public void execute(AdminCommandContext ctx) { // OK, try to give a helpful message depending on the failure if (configfailure && fsfailure) { - msg = msg + NL + NL + Strings.get("delete.instance.failed", - instanceName, instanceHost); + msg = msg + NL + NL + Strings.get("delete.instance.failed", instanceName, instanceHost); } else if (configfailure && !fsfailure) { - msg = msg + NL + NL + Strings.get("delete.instance.config.failed", - instanceName, instanceHost); + msg = msg + NL + NL + Strings.get("delete.instance.config.failed", instanceName, instanceHost); } else if (!configfailure && fsfailure) { - report.setActionExitCode(ActionReport.ExitCode.WARNING); + report.setActionExitCode(WARNING); // leave msg as is } if (configfailure) { - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); } } private void deleteInstanceFilesystem(AdminCommandContext ctx) { - - NodeUtils nodeUtils = new NodeUtils(habitat, logger); - ArrayList command = new ArrayList(); - String humanCommand = null; + NodeUtils nodeUtils = new NodeUtils(serviceLocator, logger); + ArrayList command = new ArrayList<>(); command.add("_delete-instance-filesystem"); if (nodedir != null) { command.add("--nodedir"); - command.add(nodedir); //XXX escape spaces? + command.add(nodedir); // XXX escape spaces? } command.add("--node"); @@ -218,49 +230,47 @@ private void deleteInstanceFilesystem(AdminCommandContext ctx) { command.add(instanceName); - humanCommand = makeCommandHuman(command); + String humanCommand = makeCommandHuman(command); // First error message displayed if we fail - String firstErrorMessage = Strings.get("delete.instance.filesystem.failed", - instanceName, noderef, theNode.getNodeHost() ); + String firstErrorMessage = Strings.get("delete.instance.filesystem.failed", instanceName, noderef, theNode.getNodeHost()); StringBuilder output = new StringBuilder(); // Run the command on the node and handle errors. - nodeUtils.runAdminCommandOnNode(theNode, command, ctx, firstErrorMessage, - humanCommand, output); + nodeUtils.runAdminCommandOnNode(theNode, command, ctx, firstErrorMessage, humanCommand, output); ActionReport report = ctx.getActionReport(); - if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS) { + if (report.getActionExitCode() != SUCCESS) { return; } // If it was successful say so and display the command output - String msg = Strings.get("delete.instance.success", - instanceName, theNode.getNodeHost()); + String msg = Strings.get("delete.instance.success", instanceName, theNode.getNodeHost()); if (!terse) { msg = StringUtils.cat(NL, output.toString().trim(), msg); } + report.setMessage(msg); } - private String makeCommandHuman(List command) { + private String makeCommandHuman(List commands) { StringBuilder fullCommand = new StringBuilder(); fullCommand.append("lib"); fullCommand.append(System.getProperty("file.separator")); fullCommand.append("nadmin "); - for (String s : command) { - if (s.equals("_delete-instance-filesystem")) { + for (String command : commands) { + if (command.equals("_delete-instance-filesystem")) { // We tell the user to run delete-local-instance, not the // hidden command fullCommand.append(" "); fullCommand.append("delete-local-instance"); } else { fullCommand.append(" "); - fullCommand.append(s); + fullCommand.append(command); } } diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeConfigCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeConfigCommand.java index 12c3e71106e..f4236356152 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeConfigCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeConfigCommand.java @@ -37,59 +37,61 @@ * only if the new code is made subject to such option by the copyright * holder. */ - +// Portions Copyright [2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.v3.admin.cluster; -import com.sun.enterprise.config.serverbeans.*; -import com.sun.enterprise.util.SystemPropertyConstants; -import com.sun.enterprise.util.StringUtils; +import static org.glassfish.api.ActionReport.ExitCode.FAILURE; +import static org.glassfish.api.admin.RestEndpoint.OpType.DELETE; + +import java.util.logging.Logger; + +import javax.inject.Inject; + import org.glassfish.api.ActionReport; import org.glassfish.api.I18n; import org.glassfish.api.Param; -import org.glassfish.api.admin.*; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.CommandRunner; import org.glassfish.api.admin.CommandRunner.CommandInvocation; -import javax.inject.Inject; - -import org.glassfish.hk2.api.IterableProvider; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.ParameterMap; +import org.glassfish.api.admin.RestEndpoint; +import org.glassfish.api.admin.RestEndpoints; +import org.glassfish.api.admin.RuntimeType; import org.glassfish.hk2.api.PerLookup; -import org.glassfish.hk2.api.ServiceLocator; - import org.jvnet.hk2.annotations.Service; -import org.jvnet.hk2.component.*; -import java.util.logging.Logger; + +import com.sun.enterprise.config.serverbeans.Node; +import com.sun.enterprise.config.serverbeans.Nodes; /** - * Remote AdminCommand to create a config node. This command is run only on DAS. - * Register the config node on DAS + * Remote AdminCommand to create a config node. This command is run only on DAS. + * Register the config node on DAS * * @author Carla Mott */ @Service(name = "delete-node-config") @I18n("delete.node.config") @PerLookup -@ExecuteOn({RuntimeType.DAS}) +@ExecuteOn(RuntimeType.DAS) @RestEndpoints({ - @RestEndpoint(configBean=Nodes.class, - opType=RestEndpoint.OpType.DELETE, - path="delete-node-config", - description="Delete Node Config") + @RestEndpoint(configBean = Nodes.class, + opType = DELETE, + path = "delete-node-config", + description = "Delete Node Config") }) public class DeleteNodeConfigCommand implements AdminCommand { - @Inject - ServiceLocator habitat; - @Inject - IterableProvider nodeList; + @Param(name = "name", primary = true) + private String name; @Inject - Nodes nodes; + private Nodes nodes; @Inject - private CommandRunner cr; - - @Param(name="name", primary = true) - String name; + private CommandRunner commandRunner; @Override public void execute(AdminCommandContext context) { @@ -98,28 +100,30 @@ public void execute(AdminCommandContext context) { Node node = nodes.getNode(name); if (node == null) { - //no node to delete nothing to do here + // No node to delete nothing to do here String msg = Strings.get("noSuchNode", name); logger.warning(msg); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); return; } - if (!(node.getType().equals("CONFIG") )){ - //no node to delete nothing to do here + if (!(node.getType().equals("CONFIG"))) { + // No node to delete nothing to do here String msg = Strings.get("notConfigNodeType", name); logger.warning(msg); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); return; } - CommandInvocation ci = cr.getCommandInvocation("_delete-node", report, context.getSubject()); - ParameterMap map = new ParameterMap(); - map.add("DEFAULT", name); - ci.parameters(map); - ci.execute(); + + CommandInvocation commandInvocation = commandRunner.getCommandInvocation("_delete-node", report, context.getSubject()); + ParameterMap commandParameters = new ParameterMap(); + commandParameters.add("DEFAULT", name); + commandInvocation.parameters(commandParameters); + + commandInvocation.execute(); } } diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeRemoteCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeRemoteCommand.java index 1cb3a6d51bf..cafa8d1dced 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeRemoteCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeRemoteCommand.java @@ -37,58 +37,86 @@ * only if the new code is made subject to such option by the copyright * holder. */ +// Portions Copyright [2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.v3.admin.cluster; -import java.util.List; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_INSTALLDIR; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_NODEHOST; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_REMOTEPASSWORD; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_REMOTEPORT; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_REMOTEUSER; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_SSHKEYFILE; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_SSHKEYPASSPHRASE; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_WINDOWS_DOMAIN; +import static java.util.logging.Level.FINER; +import static java.util.logging.Level.INFO; +import static org.glassfish.api.ActionReport.ExitCode.FAILURE; + +import java.io.File; import java.util.ArrayList; -import java.util.logging.Logger; +import java.util.List; import java.util.logging.Level; -import java.io.File; +import java.util.logging.Logger; + +import javax.inject.Inject; -import com.sun.enterprise.util.StringUtils; -import com.sun.enterprise.util.SystemPropertyConstants; -import com.sun.enterprise.config.serverbeans.*; import org.glassfish.api.ActionReport; import org.glassfish.api.Param; -import org.glassfish.api.admin.*; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.CommandRunner; import org.glassfish.api.admin.CommandRunner.CommandInvocation; -import javax.inject.Inject; - +import org.glassfish.api.admin.ParameterMap; import org.glassfish.hk2.api.IterableProvider; import org.glassfish.hk2.api.ServiceLocator; +import com.sun.enterprise.config.serverbeans.Node; +import com.sun.enterprise.config.serverbeans.Nodes; +import com.sun.enterprise.config.serverbeans.SshAuth; +import com.sun.enterprise.config.serverbeans.SshConnector; import com.sun.enterprise.universal.process.ProcessManager; import com.sun.enterprise.universal.process.ProcessManagerException; +import com.sun.enterprise.util.StringUtils; +import com.sun.enterprise.util.SystemPropertyConstants; /** - * Remote AdminCommand to delete a config node. This command is run only on DAS. + * Remote AdminCommand to delete a config node. This command is run only on DAS. * * @author Carla Mott */ public abstract class DeleteNodeRemoteCommand implements AdminCommand { private static final int DEFAULT_TIMEOUT_MSEC = 300000; // 5 minutes - @Inject - protected ServiceLocator habitat; - @Inject - IterableProvider nodeList; - @Inject - Nodes nodes; - @Inject - private CommandRunner cr; + private static final String NL = System.getProperty("line.separator"); + @Param(name = "name", primary = true) String name; + @Param(optional = true, defaultValue = "false") boolean uninstall; + @Param(optional = true, defaultValue = "false") boolean force; - protected String remotepassword = null; - protected String sshkeypassphrase = null; - private static final String NL = System.getProperty("line.separator"); - protected Logger logger = null; + + @Inject + protected ServiceLocator serviceLocator; + + @Inject + private CommandRunner commandRunner; + + @Inject + IterableProvider nodeList; + + @Inject + Nodes nodes; + + protected String remotepassword; + protected String sshkeypassphrase; + protected Logger logger; protected abstract List getPasswords(); protected abstract String getUninstallCommandName(); + protected abstract void setTypeSpecificOperands(List command, ParameterMap map); protected final void executeInternal(AdminCommandContext context) { @@ -97,19 +125,20 @@ protected final void executeInternal(AdminCommandContext context) { Node node = nodes.getNode(name); if (node == null) { - //no node to delete nothing to do here + // No node to delete nothing to do here String msg = Strings.get("noSuchNode", name); logger.warning(msg); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); return; } + String type = node.getType(); - if ((type == null) || (type.equals("CONFIG"))) { - //no node to delete nothing to do here + if (type == null || type.equals("CONFIG")) { + // No node to delete nothing to do here String msg = Strings.get("notRemoteNodeType", name); logger.warning(msg); - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); return; } @@ -117,37 +146,37 @@ protected final void executeInternal(AdminCommandContext context) { ParameterMap info = new ParameterMap(); if (uninstall) { - //store needed info for uninstall + // Store needed info for uninstall SshConnector sshC = node.getSshConnector(); SshAuth sshAuth = sshC.getSshAuth(); if (sshAuth.getPassword() != null) - info.add(NodeUtils.PARAM_REMOTEPASSWORD, sshAuth.getPassword()); + info.add(PARAM_REMOTEPASSWORD, sshAuth.getPassword()); if (sshAuth.getKeyPassphrase() != null) - info.add(NodeUtils.PARAM_SSHKEYPASSPHRASE, sshAuth.getKeyPassphrase()); + info.add(PARAM_SSHKEYPASSPHRASE, sshAuth.getKeyPassphrase()); if (sshAuth.getKeyfile() != null) - info.add(NodeUtils.PARAM_SSHKEYFILE, sshAuth.getKeyfile()); + info.add(PARAM_SSHKEYFILE, sshAuth.getKeyfile()); - info.add(NodeUtils.PARAM_INSTALLDIR, node.getInstallDir()); - info.add(NodeUtils.PARAM_REMOTEPORT, sshC.getSshPort()); - info.add(NodeUtils.PARAM_REMOTEUSER, sshAuth.getUserName()); - info.add(NodeUtils.PARAM_NODEHOST, node.getNodeHost()); - info.add(NodeUtils.PARAM_WINDOWS_DOMAIN, node.getWindowsDomain()); + info.add(PARAM_INSTALLDIR, node.getInstallDir()); + info.add(PARAM_REMOTEPORT, sshC.getSshPort()); + info.add(PARAM_REMOTEUSER, sshAuth.getUserName()); + info.add(PARAM_NODEHOST, node.getNodeHost()); + info.add(PARAM_WINDOWS_DOMAIN, node.getWindowsDomain()); } - CommandInvocation ci = cr.getCommandInvocation("_delete-node", report, context.getSubject()); - ParameterMap map = new ParameterMap(); - map.add("DEFAULT", name); - ci.parameters(map); - ci.execute(); + CommandInvocation commandInvocation = commandRunner.getCommandInvocation("_delete-node", report, context.getSubject()); + ParameterMap commandParameters = new ParameterMap(); + commandParameters.add("DEFAULT", name); + commandInvocation.parameters(commandParameters); + + commandInvocation.execute(); - //uninstall GlassFish after deleting the node + // Uninstall Payara after deleting the node if (uninstall) { - boolean s = uninstallNode(context, info, node); - if (!s && !force) { - report.setActionExitCode(ActionReport.ExitCode.FAILURE); + if (!uninstallNode(context, info, node) && !force) { + report.setActionExitCode(FAILURE); return; } } @@ -155,51 +184,52 @@ protected final void executeInternal(AdminCommandContext context) { /** * Prepares for invoking uninstall-node on DAS + * * @param ctx command context * @return true if uninstall-node succeeds, false otherwise */ private boolean uninstallNode(AdminCommandContext ctx, ParameterMap map, Node node) { boolean res = false; - remotepassword = map.getOne(NodeUtils.PARAM_REMOTEPASSWORD); - sshkeypassphrase = map.getOne(NodeUtils.PARAM_SSHKEYPASSPHRASE); + remotepassword = map.getOne(PARAM_REMOTEPASSWORD); + sshkeypassphrase = map.getOne(PARAM_SSHKEYPASSPHRASE); ArrayList command = new ArrayList(); command.add(getUninstallCommandName()); command.add("--installdir"); - command.add(map.getOne(NodeUtils.PARAM_INSTALLDIR)); + command.add(map.getOne(PARAM_INSTALLDIR)); if (force) { command.add("--force"); } setTypeSpecificOperands(command, map); - String host = map.getOne(NodeUtils.PARAM_NODEHOST); + String host = map.getOne(PARAM_NODEHOST); command.add(host); String firstErrorMessage = Strings.get("delete.node.ssh.uninstall.failed", node.getName(), host); StringBuilder out = new StringBuilder(); int exitCode = execCommand(command, out); - //capture the output in server.log + // capture the output in server.log logger.info(out.toString().trim()); ActionReport report = ctx.getActionReport(); if (exitCode == 0) { // If it was successful say so and display the command output - String msg = Strings.get("delete.node.ssh.uninstall.success", host); - report.setMessage(msg); + report.setMessage(Strings.get("delete.node.ssh.uninstall.success", host)); res = true; - } - else { + } else { report.setMessage(firstErrorMessage); } + return res; } /** * Invokes install-node using ProcessManager and returns the exit message/status. + * * @param cmdLine list of args * @param output contains output message * @return exit status of uninstall-node @@ -216,44 +246,44 @@ private int execCommand(List cmdLine, StringBuilder output) { File asadmin = new File(SystemPropertyConstants.getAsAdminScriptLocation(installDir)); fullcommand.add(asadmin.getAbsolutePath()); - //if password auth is used for deleting the node, use the same auth mechanism for - //uinstall-node as well. The passwords are passed directly through input stream - List pass = new ArrayList(); + // if password auth is used for deleting the node, use the same auth mechanism for + // uinstall-node as well. The passwords are passed directly through input stream + List passwords = new ArrayList(); if (remotepassword != null) { fullcommand.add("--passwordfile"); fullcommand.add("-"); - pass = getPasswords(); + passwords = getPasswords(); } fullcommand.add("--interactive=false"); fullcommand.addAll(cmdLine); - ProcessManager pm = new ProcessManager(fullcommand); - if (!pass.isEmpty()) - pm.setStdinLines(pass); + ProcessManager processManager = new ProcessManager(fullcommand); + if (!passwords.isEmpty()) + processManager.setStdinLines(passwords); - if (logger.isLoggable(Level.INFO)) { + if (logger.isLoggable(INFO)) { logger.info("Running command on DAS: " + commandListToString(fullcommand)); } - pm.setTimeoutMsec(DEFAULT_TIMEOUT_MSEC); + + processManager.setTimeoutMsec(DEFAULT_TIMEOUT_MSEC); - if (logger.isLoggable(Level.FINER)) - pm.setEcho(true); + if (logger.isLoggable(FINER)) + processManager.setEcho(true); else - pm.setEcho(false); + processManager.setEcho(false); try { - exit = pm.execute(); - } - catch (ProcessManagerException ex) { + exit = processManager.execute(); + } catch (ProcessManagerException ex) { if (logger.isLoggable(Level.FINE)) { logger.fine("Error while executing command: " + ex.getMessage()); } exit = 1; } - String stdout = pm.getStdout(); - String stderr = pm.getStderr(); + String stdout = processManager.getStdout(); + String stderr = processManager.getStderr(); if (output != null) { if (StringUtils.ok(stdout)) { @@ -273,9 +303,9 @@ private int execCommand(List cmdLine, StringBuilder output) { private String commandListToString(List command) { StringBuilder fullCommand = new StringBuilder(); - for (String s : command) { + for (String commandPart : command) { fullCommand.append(" "); - fullCommand.append(s); + fullCommand.append(commandPart); } return fullCommand.toString(); diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeSshCommand.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeSshCommand.java index 6e267c864a7..580175828dd 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeSshCommand.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/DeleteNodeSshCommand.java @@ -37,20 +37,30 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.v3.admin.cluster; -import java.util.*; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_REMOTEPORT; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_REMOTEUSER; +import static com.sun.enterprise.v3.admin.cluster.NodeUtils.PARAM_SSHKEYFILE; +import static org.glassfish.api.admin.RestEndpoint.OpType.DELETE; + +import java.util.ArrayList; +import java.util.List; -import com.sun.enterprise.config.serverbeans.*; import org.glassfish.api.I18n; -import org.glassfish.api.admin.*; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.ParameterMap; +import org.glassfish.api.admin.RestEndpoint; +import org.glassfish.api.admin.RestEndpoints; +import org.glassfish.api.admin.RuntimeType; import org.glassfish.hk2.api.PerLookup; - - import org.jvnet.hk2.annotations.Service; +import com.sun.enterprise.config.serverbeans.Nodes; + /** * Remote AdminCommand to create a config node. This command is run only on DAS. @@ -61,48 +71,53 @@ @Service(name = "delete-node-ssh") @I18n("delete.node.ssh") @PerLookup -@ExecuteOn({RuntimeType.DAS}) +@ExecuteOn(RuntimeType.DAS) @RestEndpoints({ - @RestEndpoint(configBean=Nodes.class, - opType=RestEndpoint.OpType.DELETE, - path="delete-node-ssh", - description="Delete Node SSH") + @RestEndpoint(configBean = Nodes.class, + opType = DELETE, + path = "delete-node-ssh", + description = "Delete Node SSH") }) public class DeleteNodeSshCommand extends DeleteNodeRemoteCommand { + @Override public final void execute(AdminCommandContext context) { executeInternal(context); } + /** * Get list of password file entries + * * @return List */ @Override protected final List getPasswords() { - List list = new ArrayList(); - NodeUtils nodeUtils = new NodeUtils(habitat, logger); - list.add("AS_ADMIN_SSHPASSWORD=" + nodeUtils.sshL.expandPasswordAlias(remotepassword)); + List passwords = new ArrayList<>(); + NodeUtils nodeUtils = new NodeUtils(serviceLocator, logger); + + passwords.add("AS_ADMIN_SSHPASSWORD=" + nodeUtils.sshL.expandPasswordAlias(remotepassword)); if (sshkeypassphrase != null) { - list.add("AS_ADMIN_SSHKEYPASSPHRASE=" + nodeUtils.sshL.expandPasswordAlias(sshkeypassphrase)); + passwords.add("AS_ADMIN_SSHKEYPASSPHRASE=" + nodeUtils.sshL.expandPasswordAlias(sshkeypassphrase)); } - return list; + + return passwords; } @Override protected String getUninstallCommandName() { return "uninstall-node-ssh"; } - + @Override - final protected void setTypeSpecificOperands(List command, ParameterMap map) { + final protected void setTypeSpecificOperands(List command, ParameterMap commandParameters) { command.add("--sshport"); - command.add(map.getOne(NodeUtils.PARAM_REMOTEPORT)); + command.add(commandParameters.getOne(PARAM_REMOTEPORT)); command.add("--sshuser"); - command.add(map.getOne(NodeUtils.PARAM_REMOTEUSER)); + command.add(commandParameters.getOne(PARAM_REMOTEUSER)); - String key = map.getOne(NodeUtils.PARAM_SSHKEYFILE); + String key = commandParameters.getOne(PARAM_SSHKEYFILE); if (key != null) { command.add("--sshkeyfile"); diff --git a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/ExportSyncBundle.java b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/ExportSyncBundle.java index 801e36e39ab..83f43e065e3 100644 --- a/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/ExportSyncBundle.java +++ b/nucleus/cluster/admin/src/main/java/com/sun/enterprise/v3/admin/cluster/ExportSyncBundle.java @@ -37,28 +37,51 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.v3.admin.cluster; -import com.sun.enterprise.config.serverbeans.*; -import com.sun.enterprise.universal.io.SmartFile; -import com.sun.enterprise.util.cluster.SyncRequest; -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.logging.*; +import static java.util.logging.Level.FINER; +import static java.util.logging.Level.SEVERE; +import static org.glassfish.api.ActionReport.ExitCode.FAILURE; +import static org.glassfish.api.ActionReport.ExitCode.SUCCESS; +import static org.glassfish.api.admin.RestEndpoint.OpType.POST; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URI; +import java.util.List; +import java.util.Properties; +import java.util.logging.Logger; + import javax.inject.Inject; + import org.glassfish.admin.payload.PayloadImpl; import org.glassfish.api.ActionReport; -import org.glassfish.api.ActionReport.ExitCode; import org.glassfish.api.I18n; import org.glassfish.api.Param; -import org.glassfish.api.admin.*; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.glassfish.api.admin.ExecuteOn; +import org.glassfish.api.admin.Payload; +import org.glassfish.api.admin.RestEndpoint; +import org.glassfish.api.admin.RestEndpoints; +import org.glassfish.api.admin.RuntimeType; +import org.glassfish.api.admin.ServerEnvironment; +import org.glassfish.hk2.api.PerLookup; import org.jvnet.hk2.annotations.Optional; - import org.jvnet.hk2.annotations.Service; -import org.glassfish.hk2.api.PerLookup; + +import com.sun.enterprise.config.serverbeans.Cluster; +import com.sun.enterprise.config.serverbeans.Clusters; +import com.sun.enterprise.config.serverbeans.Domain; +import com.sun.enterprise.config.serverbeans.Server; +import com.sun.enterprise.config.serverbeans.Servers; +import com.sun.enterprise.universal.io.SmartFile; +import com.sun.enterprise.util.cluster.SyncRequest; /** * Usage:
    @@ -78,107 +101,115 @@ * @author Byron Nevins * @author Jennifer Chou */ -@org.glassfish.api.admin.ExecuteOn(RuntimeType.DAS) +@ExecuteOn(RuntimeType.DAS) @Service(name = "export-sync-bundle") @PerLookup -//@TargetType(value={CommandTarget.CLUSTER, CommandTarget.STANDALONE_INSTANCE}) @I18n("export-sync-bundle") @RestEndpoints({ - @RestEndpoint(configBean=Domain.class, - opType=RestEndpoint.OpType.POST, - path="export-sync-bundle", - description="export-sync-bundle") + @RestEndpoint(configBean = Domain.class, + opType = POST, + path = "export-sync-bundle", + description = "export-sync-bundle") }) public class ExportSyncBundle implements AdminCommand { + + private static final String[] ALL_DIRS = new String[] { "config", "applications", "lib", "docroot", "config-specific" }; + private static final String SYNC_FAIL = "export.sync.bundle.fail"; - @Param(name="target", optional = false) + @Param(name = "target", optional = false) private String clusterInstance; - @Param(name="retrieve", optional = true, defaultValue="false") + + @Param(name = "retrieve", optional = true, defaultValue = "false") private boolean isRetrieve; + @Param(optional = true, primary = true) String file_name; - - @Inject @Optional + + @Inject + @Optional private Servers servers; - @Inject @Optional + + @Inject + @Optional private Clusters clusters; + @Inject private ServerSynchronizer serverSynchronizer; - @Inject + @Inject private ServerEnvironment env; - private ActionReport report = null; + + private SyncRequest syncRequest = new SyncRequest(); + + private ActionReport report; private File syncBundleExport; - private Logger logger = null; - private Payload.Outbound payload = null; + private Logger logger; + private Payload.Outbound payload; private Server instance; private Cluster cluster; - private SyncRequest syncRequest = new SyncRequest(); - private static final String[] ALL_DIRS = new String[]{ - "config", "applications", "lib", "docroot", "config-specific" - }; - - private static final String SYNC_FAIL = "export.sync.bundle.fail"; @Override public void execute(AdminCommandContext context) { report = context.getActionReport(); - report.setActionExitCode(ExitCode.SUCCESS); + report.setActionExitCode(SUCCESS); logger = context.getLogger(); - // we use our own private payload. Don't use the one in the context! + // We use our own private payload. Don't use the one in the context! payload = PayloadImpl.Outbound.newInstance(); - try { - if (!isValid()) + if (!isValid()) { return; + } - if (!setSyncBundleExportFile()) + if (!setSyncBundleExportFile()) { return; + } syncRequest = new SyncRequest(); syncRequest.instance = clusterInstance; - if (!sync()) + if (!sync()) { return; + } // write to the das or temp file write(); - //all OK...download local file - if (isRetrieve) + // all OK...download local file + if (isRetrieve) { pumpItOut(context); - } - catch (Exception e) { + } + } catch (Exception e) { setError(Strings.get(SYNC_FAIL, e.toString())); - logger.log(Level.SEVERE, Strings.get(SYNC_FAIL, e.toString()), e); + logger.log(SEVERE, Strings.get(SYNC_FAIL, e.toString()), e); } } private void pumpItOut(AdminCommandContext context) { String fileName = file_name != null && !file_name.isEmpty() ? file_name : getDefaultBundleName(); File localFile = new File(fileName.replace('\\', '/')); - Properties props = new Properties(); + File parent = localFile.getParentFile(); if (parent == null) { parent = localFile; } + + Properties props = new Properties(); props.setProperty("file-xfer-root", parent.getPath().replace('\\', '/')); URI parentURI = parent.toURI(); try { - context.getOutboundPayload().attachFile( - "application/octet-stream", - parentURI.relativize(localFile.toURI()), - "sync-bundle", - props, - syncBundleExport); + context.getOutboundPayload() + .attachFile( + "application/octet-stream", + parentURI.relativize(localFile.toURI()), "sync-bundle", + props, syncBundleExport); } catch (IOException ex) { setError(Strings.get("export.sync.bundle.retrieveFailed", ex.getLocalizedMessage())); - if (logger.isLoggable(Level.FINER)) { - logger.log(Level.FINER, "fileURI: {0}", parentURI.relativize(localFile.toURI())); - logger.log(Level.FINER, "file-xfer-root: {0}", parent.getPath().replace('\\', '/')); - logger.log(Level.FINER, "file: {0}", syncBundleExport.getAbsolutePath()); + if (logger.isLoggable(FINER)) { + logger.log(FINER, "fileURI: {0}", parentURI.relativize(localFile.toURI())); + logger.log(FINER, "file-xfer-root: {0}", parent.getPath().replace('\\', '/')); + logger.log(FINER, "file: {0}", syncBundleExport.getAbsolutePath()); } } } @@ -187,8 +218,9 @@ private boolean sync() { for (String dir : ALL_DIRS) { syncRequest.dir = dir; - if (!syncOne()) + if (!syncOne()) { return false; + } } return !hasError(); @@ -200,18 +232,17 @@ private void write() { out = new BufferedOutputStream(new FileOutputStream(syncBundleExport)); payload.writeTo(out); } catch (IOException ex) { - setError(Strings.get("export.sync.bundle.exportFailed", - syncBundleExport.getAbsolutePath(), ex.getLocalizedMessage())); + setError(Strings.get("export.sync.bundle.exportFailed", syncBundleExport.getAbsolutePath(), ex.getLocalizedMessage())); } finally { if (out != null) { try { out.close(); } catch (IOException ex) { - logger.warning(Strings.get("export.sync.bundle.closeStreamFailed", - syncBundleExport.getAbsolutePath(), ex.getLocalizedMessage())); + logger.warning(Strings.get("export.sync.bundle.closeStreamFailed", syncBundleExport.getAbsolutePath(), ex.getLocalizedMessage())); } } } + if (!isRetrieve) { if (syncBundleExport.isFile()) { report.setMessage(Strings.get("export.sync.bundle.success", syncBundleExport.getAbsolutePath())); @@ -225,15 +256,15 @@ private boolean syncOne() { if (instance != null) { serverSynchronizer.synchronize(instance, syncRequest, payload, report, logger); } + if (cluster != null) { // Use one of the clustered instances - List slist = cluster.getInstances(); - if (slist != null && !slist.isEmpty()) { - Server s = slist.get(0); - serverSynchronizer.synchronize(s, syncRequest, payload, report, logger); + List clusterInstances = cluster.getInstances(); + if (clusterInstances != null && !clusterInstances.isEmpty()) { + serverSynchronizer.synchronize(clusterInstances.get(0), syncRequest, payload, report, logger); } } - // synchronize() will be set to FAILURE if there were problems + // Synchronize() will be set to FAILURE if there were problems return !hasError(); } @@ -246,14 +277,16 @@ private String getDefaultBundleName() { } private boolean isValid() { - // verify the cluster or stand-alone server name corresponds to reality! - if (servers != null) + // Verify the cluster or stand-alone server name corresponds to reality! + if (servers != null) { instance = servers.getServer(clusterInstance); + } + if (clusters != null) { cluster = clusters.getCluster(clusterInstance); if (cluster != null) { - List list = cluster.getInstances(); - if (list == null || list.isEmpty()) { + List clusterInstances = cluster.getInstances(); + if (clusterInstances == null || clusterInstances.isEmpty()) { setError(Strings.get("sync.empty_cluster", clusterInstance)); return false; } @@ -278,36 +311,37 @@ private boolean setSyncBundleExportFile() { return false; } } else { - File f = null; + File file = null; if (file_name != null && !file_name.isEmpty()) { - f = new File(file_name); - if (f.isDirectory()) { - //Existing directory specified, -sync-bundle.zip is created in specified directory. - f = new File(f, getDefaultBundleName()); + file = new File(file_name); + if (file.isDirectory()) { + // Existing directory specified, -sync-bundle.zip is created in specified directory. + file = new File(file, getDefaultBundleName()); } } else { - //No operand specified, -sync-bundle.zip is created in install-root/domains/domain_name/sync - f = getDefaultBundle(); + // No operand specified, -sync-bundle.zip is created in install-root/domains/domain_name/sync + file = getDefaultBundle(); } - - if (f.getParentFile() != null && !f.getParentFile().exists()) { - if (!f.getParentFile().mkdirs()) { - setError(Strings.get("export.sync.bundle.createDirFailed", f.getParentFile().getPath())); + + if (file.getParentFile() != null && !file.getParentFile().exists()) { + if (!file.getParentFile().mkdirs()) { + setError(Strings.get("export.sync.bundle.createDirFailed", file.getParentFile().getPath())); return false; } } - syncBundleExport = SmartFile.sanitize(f); + syncBundleExport = SmartFile.sanitize(file); } + return true; } private void setError(String msg) { - report.setActionExitCode(ExitCode.FAILURE); + report.setActionExitCode(FAILURE); report.setMessage(msg); } private boolean hasError() { - return report.getActionExitCode() != ExitCode.SUCCESS; + return report.getActionExitCode() != SUCCESS; } - + } From 849ff1bb8d83861a49ef113a472f33c703b5d8c8 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Fri, 15 Mar 2019 18:03:57 +0100 Subject: [PATCH 035/108] PAYARA-3466 FIXED Extensible no longer adds node 'extensions' to JSON --- .../microprofile/openapi/impl/model/ExtensibleImpl.java | 2 ++ .../microprofile/openapi/impl/model/ExtensibleTreeMap.java | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index c549ef80659..44989012b07 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -51,6 +51,7 @@ import org.eclipse.microprofile.openapi.annotations.extensions.Extension; import org.eclipse.microprofile.openapi.models.Extensible; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -58,6 +59,7 @@ public abstract class ExtensibleImpl> implements Extensi private static final Logger LOGGER = Logger.getLogger(ExtensibleImpl.class.getName()); + @JsonIgnore protected Map extensions = new LinkedHashMap<>(); @Override diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java index 8ed4c5ea37c..77c65793f9b 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java @@ -6,9 +6,12 @@ import org.eclipse.microprofile.openapi.models.Extensible; +import com.fasterxml.jackson.annotation.JsonIgnore; + public abstract class ExtensibleTreeMap> extends TreeMap implements Extensible { + @JsonIgnore protected Map extensions = new LinkedHashMap<>(); protected ExtensibleTreeMap() { @@ -32,7 +35,7 @@ public final void setExtensions(Map extensions) { @SuppressWarnings("unchecked") @Override public final T addExtension(String name, Object value) { - if (value != null) { + if (value != null && name.startsWith("x-")) { this.extensions.put(name, value); } return (T) this; From 3d29846b120a54dc38d922f684d0c92134b602fa Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Fri, 15 Mar 2019 18:05:24 +0100 Subject: [PATCH 036/108] PAYARA-3466 basic tests and basis for JSON output testing --- .../impl/model/ModelInvariantsTest.java | 149 +++++++ .../impl/model/ModelSerialisationTest.java | 58 +++ .../openapi/impl/model/ModelTestUtil.java | 33 ++ .../microprofile/openapi/spec/Field.java | 57 +++ .../microprofile/openapi/spec/NodeType.java | 374 ++++++++++++++++++ .../openapi/spec/OpenAPIValidator.java | 148 +++++++ .../openapi/spec/OpenAPIValidatorTest.java | 37 ++ .../openapi/src/test/resources/Callback.json | 21 + .../src/test/resources/Components.json | 87 ++++ .../openapi/src/test/resources/Contact.json | 5 + .../src/test/resources/Discriminator.json | 7 + .../openapi/src/test/resources/Encoding.json | 16 + .../openapi/src/test/resources/Example.json | 12 + .../test/resources/ExternalDocumentation.json | 4 + .../openapi/src/test/resources/Header.json | 6 + .../openapi/src/test/resources/Info.json | 15 + .../openapi/src/test/resources/License.json | 4 + .../openapi/src/test/resources/Link.json | 14 + .../openapi/src/test/resources/MediaType.json | 31 ++ .../src/test/resources/OAuthFlows.json | 17 + .../openapi/src/test/resources/Operation.json | 62 +++ .../openapi/src/test/resources/Parameter.json | 73 ++++ .../openapi/src/test/resources/PathItem.json | 47 +++ .../openapi/src/test/resources/Paths.json | 22 ++ .../openapi/src/test/resources/Reference.json | 11 + .../src/test/resources/RequestBody.json | 58 +++ .../openapi/src/test/resources/Response.json | 58 +++ .../openapi/src/test/resources/Responses.json | 22 ++ .../openapi/src/test/resources/Schema.json | 159 ++++++++ .../test/resources/SecurityRequirement.json | 11 + .../src/test/resources/SecurityScheme.json | 28 ++ .../openapi/src/test/resources/Server.json | 4 + .../src/test/resources/ServerVariable.json | 10 + .../openapi/src/test/resources/Tag.json | 4 + .../openapi/src/test/resources/XML.json | 10 + 35 files changed, 1674 insertions(+) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelTestUtil.java create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidatorTest.java create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Callback.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Components.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Contact.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Discriminator.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Encoding.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Example.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/ExternalDocumentation.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Header.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Info.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/License.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Link.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/MediaType.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/OAuthFlows.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Operation.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Parameter.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/PathItem.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Paths.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Reference.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/RequestBody.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Response.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Responses.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Schema.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/SecurityRequirement.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/SecurityScheme.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Server.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/ServerVariable.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Tag.json create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/XML.json diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java new file mode 100644 index 00000000000..324295dab14 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java @@ -0,0 +1,149 @@ +package fish.payara.microprofile.openapi.impl.model; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import java.util.function.BiPredicate; + +import org.eclipse.microprofile.openapi.models.Components; +import org.eclipse.microprofile.openapi.models.Extensible; +import org.eclipse.microprofile.openapi.models.ExternalDocumentation; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.Operation; +import org.eclipse.microprofile.openapi.models.PathItem; +import org.eclipse.microprofile.openapi.models.Paths; +import org.eclipse.microprofile.openapi.models.callbacks.Callback; +import org.eclipse.microprofile.openapi.models.examples.Example; +import org.eclipse.microprofile.openapi.models.headers.Header; +import org.eclipse.microprofile.openapi.models.info.Contact; +import org.eclipse.microprofile.openapi.models.info.Info; +import org.eclipse.microprofile.openapi.models.info.License; +import org.eclipse.microprofile.openapi.models.links.Link; +import org.eclipse.microprofile.openapi.models.media.Content; +import org.eclipse.microprofile.openapi.models.media.Discriminator; +import org.eclipse.microprofile.openapi.models.media.Encoding; +import org.eclipse.microprofile.openapi.models.media.MediaType; +import org.eclipse.microprofile.openapi.models.media.Schema; +import org.eclipse.microprofile.openapi.models.media.XML; +import org.eclipse.microprofile.openapi.models.parameters.Parameter; +import org.eclipse.microprofile.openapi.models.parameters.RequestBody; +import org.eclipse.microprofile.openapi.models.responses.APIResponse; +import org.eclipse.microprofile.openapi.models.responses.APIResponses; +import org.eclipse.microprofile.openapi.models.security.OAuthFlow; +import org.eclipse.microprofile.openapi.models.security.OAuthFlows; +import org.eclipse.microprofile.openapi.models.security.Scopes; +import org.eclipse.microprofile.openapi.models.security.SecurityScheme; +import org.eclipse.microprofile.openapi.models.servers.Server; +import org.eclipse.microprofile.openapi.models.servers.ServerVariable; +import org.eclipse.microprofile.openapi.models.servers.ServerVariables; +import org.eclipse.microprofile.openapi.models.tags.Tag; +import org.junit.Test; + +import fish.payara.microprofile.openapi.impl.model.callbacks.CallbackImpl; +import fish.payara.microprofile.openapi.impl.model.examples.ExampleImpl; +import fish.payara.microprofile.openapi.impl.model.headers.HeaderImpl; +import fish.payara.microprofile.openapi.impl.model.info.ContactImpl; +import fish.payara.microprofile.openapi.impl.model.info.InfoImpl; +import fish.payara.microprofile.openapi.impl.model.info.LicenseImpl; +import fish.payara.microprofile.openapi.impl.model.links.LinkImpl; +import fish.payara.microprofile.openapi.impl.model.media.ContentImpl; +import fish.payara.microprofile.openapi.impl.model.media.DiscriminatorImpl; +import fish.payara.microprofile.openapi.impl.model.media.EncodingImpl; +import fish.payara.microprofile.openapi.impl.model.media.MediaTypeImpl; +import fish.payara.microprofile.openapi.impl.model.media.SchemaImpl; +import fish.payara.microprofile.openapi.impl.model.media.XMLImpl; +import fish.payara.microprofile.openapi.impl.model.parameters.ParameterImpl; +import fish.payara.microprofile.openapi.impl.model.parameters.RequestBodyImpl; +import fish.payara.microprofile.openapi.impl.model.responses.APIResponseImpl; +import fish.payara.microprofile.openapi.impl.model.responses.APIResponsesImpl; +import fish.payara.microprofile.openapi.impl.model.security.OAuthFlowImpl; +import fish.payara.microprofile.openapi.impl.model.security.OAuthFlowsImpl; +import fish.payara.microprofile.openapi.impl.model.security.ScopesImpl; +import fish.payara.microprofile.openapi.impl.model.security.SecuritySchemeImpl; +import fish.payara.microprofile.openapi.impl.model.servers.ServerImpl; +import fish.payara.microprofile.openapi.impl.model.servers.ServerVariableImpl; +import fish.payara.microprofile.openapi.impl.model.servers.ServerVariablesImpl; +import fish.payara.microprofile.openapi.impl.model.tags.TagImpl; + +public class ModelInvariantsTest { + + interface HasAdd { + + T add(T obj, String key, V value); + } + + @Test + public void addKeyValueIgnoresNull() { + BiPredicate, String> hasExtension = (obj, key) -> obj.getExtensions().containsKey(key); + assertAddIgnoresNull(new CallbackImpl(), Callback::addPathItem, Callback::hasPathItem); + assertAddIgnoresNull(new CallbackImpl(), Callback::addExtension, hasExtension); + assertAddIgnoresNull(new ExampleImpl(), Example::addExtension, hasExtension); + assertAddIgnoresNull(new HeaderImpl(), Header::addExample, (obj, key) -> obj.getExamples().containsKey(key)); + assertAddIgnoresNull(new HeaderImpl(), Header::addExtension, hasExtension); + assertAddIgnoresNull(new ContactImpl(), Contact::addExtension, hasExtension); + assertAddIgnoresNull(new InfoImpl(), Info::addExtension, hasExtension); + assertAddIgnoresNull(new LicenseImpl(), License::addExtension, hasExtension); + assertAddIgnoresNull(new LinkImpl(), Link::addParameter, (obj, key) -> obj.getParameters().containsKey(key)); + assertAddIgnoresNull(new LinkImpl(), Link::addExtension, hasExtension); + assertAddIgnoresNull(new ContentImpl(), Content::addMediaType, Content::hasMediaType); + assertAddIgnoresNull(new DiscriminatorImpl(), Discriminator::addMapping, (obj, key) -> obj.getMapping().containsKey(key)); + assertAddIgnoresNull(new EncodingImpl(), Encoding::addHeader, (obj, key) -> obj.getHeaders().containsKey(key)); + assertAddIgnoresNull(new EncodingImpl(), Encoding::addExtension, hasExtension); + assertAddIgnoresNull(new MediaTypeImpl(), MediaType::addEncoding, (obj, key) -> obj.getEncoding().containsKey(key)); + assertAddIgnoresNull(new MediaTypeImpl(), MediaType::addExample, (obj, key) -> obj.getExamples().containsKey(key)); + assertAddIgnoresNull(new MediaTypeImpl(), MediaType::addExtension, hasExtension); + assertAddIgnoresNull(new SchemaImpl(), Schema::addProperty, (obj, key) -> obj.getProperties().containsKey(key)); + assertAddIgnoresNull(new SchemaImpl(), Schema::addExtension, hasExtension); + assertAddIgnoresNull(new XMLImpl(), XML::addExtension, hasExtension); + assertAddIgnoresNull(new ParameterImpl(), Parameter::addExample, (obj, key) -> obj.getExamples().containsKey(key)); + assertAddIgnoresNull(new ParameterImpl(), Parameter::addExtension, hasExtension); + assertAddIgnoresNull(new RequestBodyImpl(), RequestBody::addExtension, hasExtension); + assertAddIgnoresNull(new APIResponseImpl(), APIResponse::addHeader, (obj, key) -> obj.getHeaders().containsKey(key)); + assertAddIgnoresNull(new APIResponseImpl(), APIResponse::addLink, (obj, key) -> obj.getLinks().containsKey(key)); + assertAddIgnoresNull(new APIResponseImpl(), APIResponse::addExtension, hasExtension); + assertAddIgnoresNull(new APIResponsesImpl(), APIResponses::addApiResponse, APIResponses::hasAPIResponse); + assertAddIgnoresNull(new APIResponsesImpl(), APIResponses::addAPIResponse, APIResponses::hasAPIResponse); + assertAddIgnoresNull(new APIResponsesImpl(), APIResponses::addExtension, hasExtension); + assertAddIgnoresNull(new OAuthFlowImpl(), OAuthFlow::addExtension, hasExtension); + assertAddIgnoresNull(new OAuthFlowsImpl(), OAuthFlows::addExtension, hasExtension); + assertAddIgnoresNull(new ScopesImpl(), Scopes::addExtension, hasExtension); + assertAddIgnoresNull(new SecuritySchemeImpl(), SecurityScheme::addExtension, hasExtension); + assertAddIgnoresNull(new ServerImpl(), Server::addExtension, hasExtension); + assertAddIgnoresNull(new ServerVariableImpl(), ServerVariable::addExtension, hasExtension); + assertAddIgnoresNull(new ServerVariablesImpl(), ServerVariables::addServerVariable, ServerVariables::hasServerVariable); + assertAddIgnoresNull(new ServerVariablesImpl(), ServerVariables::addExtension, hasExtension); + assertAddIgnoresNull(new TagImpl(), Tag::addExtension, hasExtension); + assertAddIgnoresNull(new ComponentsImpl(), Components::addCallback, (obj, key) -> obj.getCallbacks().containsKey(key)); + assertAddIgnoresNull(new ComponentsImpl(), Components::addExample, (obj, key) -> obj.getExamples().containsKey(key)); + assertAddIgnoresNull(new ComponentsImpl(), Components::addHeader, (obj, key) -> obj.getHeaders().containsKey(key)); + assertAddIgnoresNull(new ComponentsImpl(), Components::addLink, (obj, key) -> obj.getLinks().containsKey(key)); + assertAddIgnoresNull(new ComponentsImpl(), Components::addParameter, (obj, key) -> obj.getParameters().containsKey(key)); + assertAddIgnoresNull(new ComponentsImpl(), Components::addRequestBody, (obj, key) -> obj.getRequestBodies().containsKey(key)); + assertAddIgnoresNull(new ComponentsImpl(), Components::addResponse, (obj, key) -> obj.getResponses().containsKey(key)); + assertAddIgnoresNull(new ComponentsImpl(), Components::addSchema, (obj, key) -> obj.getSchemas().containsKey(key)); + assertAddIgnoresNull(new ComponentsImpl(), Components::addSecurityScheme, (obj, key) -> obj.getSecuritySchemes().containsKey(key)); + assertAddIgnoresNull(new ComponentsImpl(), Components::addExtension, hasExtension); + assertAddIgnoresNull(new ExternalDocumentationImpl(), ExternalDocumentation::addExtension, hasExtension); + assertAddIgnoresNull(new OpenAPIImpl(), OpenAPI::addExtension, hasExtension); + assertAddIgnoresNull(new OperationImpl(), Operation::addCallback, (obj, key) -> obj.getCallbacks().containsKey(key)); + assertAddIgnoresNull(new OperationImpl(), Operation::addExtension, hasExtension); + assertAddIgnoresNull(new PathItemImpl(), PathItem::addExtension, hasExtension); + assertAddIgnoresNull(new PathsImpl(), Paths::addPathItem, Paths::hasPathItem); + assertAddIgnoresNull(new PathsImpl(), Paths::addExtension, hasExtension); + } + + @Test + public void ScopesAddScopeDoesAcceptNull() { + Scopes scopes = new ScopesImpl().addScope("foo", null); + assertTrue(scopes.hasScope("foo")); + } + + private static void assertAddIgnoresNull(T modelObject, HasAdd addMethod, BiPredicate containsMethod) { + String key = "whatever"; + T res = addMethod.add(modelObject, key, null); + String typeName = modelObject.getClass().getSimpleName(); + assertSame(typeName + " add should return same instance for chaining but doesn't", res, modelObject); + assertFalse(typeName + " add should not create an entry for key if value is null but does", containsMethod.test(modelObject, key)); + } +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java new file mode 100644 index 00000000000..b1a0b93ab9c --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java @@ -0,0 +1,58 @@ +package fish.payara.microprofile.openapi.impl.model; + +import static fish.payara.microprofile.openapi.impl.model.ModelTestUtil.newCallback; +import static fish.payara.microprofile.openapi.impl.model.ModelTestUtil.newCallbackRef; +import static fish.payara.microprofile.openapi.impl.model.ModelTestUtil.newPathItemRef; +import static org.junit.Assert.assertNotNull; + +import org.eclipse.microprofile.openapi.models.Constructible; +import org.eclipse.microprofile.openapi.models.examples.Example; +import org.junit.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import fish.payara.microprofile.openapi.impl.model.examples.ExampleImpl; +import fish.payara.microprofile.openapi.impl.rest.app.provider.ObjectMapperFactory; +import fish.payara.microprofile.openapi.spec.NodeType; +import fish.payara.microprofile.openapi.spec.OpenAPIValidator; + +/** + * A test that should help detect (and thereby avoid) changes in the model that do serialise to an non valid Open API + * document. This can happen quite easily since we use "automatic" serialisation with jackson that picks up getters + * (unless explicitly told not to). This might not seem a big thing at first but adding anything to the document that + * isn't expected or allowed makes the resulting Open API document invalid. Therefore this test creates model objects, + * serialises them to JSON and validates the tree against the Open API specification as modeled by {@link NodeType}. + */ +public class ModelSerialisationTest { + + private static final ObjectMapper JSON_MAPPER = ObjectMapperFactory.createJson(); + + @Test + public void callbackWithRef() { + assertValid(NodeType.Callback, newCallbackRef("#/components/schemas/SomePayload")); + } + + @Test + public void callbackWithPathItem() { + assertValid(NodeType.Callback, newCallback("foo", newPathItemRef("#bar"))); + } + + @Test + public void callbackWithExtension() { + assertValid(NodeType.Callback, newCallbackRef("#/components/schemas/SomePayload") + .addExtension("hello", "world")); + } + + @Test + public void exampleWithExtension() { + Example ex = new ExampleImpl(); + ex = ex.addExtension("x-hello", "world"); + assertValid(NodeType.Example, ex); + } + + private static void assertValid(NodeType type, Constructible node) { + assertNotNull("The example tested should not be null", node); + OpenAPIValidator.validate(type, JSON_MAPPER.valueToTree(node)); + } + +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelTestUtil.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelTestUtil.java new file mode 100644 index 00000000000..c41e12aa146 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelTestUtil.java @@ -0,0 +1,33 @@ +package fish.payara.microprofile.openapi.impl.model; + +import java.util.Collections; +import java.util.function.Supplier; + +import org.eclipse.microprofile.openapi.models.PathItem; +import org.eclipse.microprofile.openapi.models.Reference; +import org.eclipse.microprofile.openapi.models.callbacks.Callback; + +import fish.payara.microprofile.openapi.impl.model.callbacks.CallbackImpl; + +public class ModelTestUtil { + + static Callback newCallbackRef(String ref) { + return newRef(ref, CallbackImpl::new); + } + + static Callback newCallback(String expression, PathItem item) { + Callback callback = new CallbackImpl(); + callback.setPathItems(Collections.singletonMap(expression, item)); + return callback; + } + + static PathItem newPathItemRef(String ref) { + return newRef(ref, PathItemImpl::new); + } + + private static > T newRef(String ref, Supplier constructor) { + T reference = constructor.get(); + reference.setRef(ref); + return reference; + } +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java new file mode 100644 index 00000000000..c9e8ff0e2b2 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java @@ -0,0 +1,57 @@ +package fish.payara.microprofile.openapi.spec; + +import java.util.EnumSet; +import java.util.Iterator; + +public final class Field implements Iterable { + + private static final NodeType[] ALL_NODE_TYPES = NodeType.values(); + + final String name; + final EnumSet oneOfTypes = EnumSet.noneOf(NodeType.class); + boolean isRequired = false; + boolean isArray = false; + boolean isMap = false; + + Field(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public boolean isRequired() { + return isRequired; + } + + public boolean isMap() { + return isMap; + } + + public boolean isArray() { + return isArray; + } + + public boolean isOneOfManyTypes() { + return oneOfTypes.size() > 0; + } + + public boolean isAnyType() { + return oneOfTypes.isEmpty(); + } + + public NodeType type() { + return oneOfTypes.iterator().next(); + } + + @Override + public Iterator iterator() { + return oneOfTypes.iterator(); + } + + @Override + public String toString() { + return name + ": " + oneOfTypes.toString(); + } +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java new file mode 100644 index 00000000000..e3e55c5853d --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java @@ -0,0 +1,374 @@ +package fish.payara.microprofile.openapi.spec; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.stream.Stream; + +/** + * Node types and their structure as described by Open API Specification + * {@link https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md}. + */ +public enum NodeType implements Iterable { + + // primitive elements + string, + bool, + number, + // non primitive elements + OpenAPI, + Info, + Contact, + License, + Server, + ServerVariable, + Components, + Paths, + PathItem, + Operation, + ExternalDocumentation, + Parameter, + RequestBody, + MediaType, + Encoding, + Responses, + Response, + Callback, + Example, + Link, + Header, + Tag, + Reference, + Schema, + Discriminator, + XML, + SecurityScheme, + OAuthFlows, + OAuthFlow, + SecurityRequirement + ; + + private boolean isExtensible = false; + private final Map fields = new LinkedHashMap<>(); + private Field lastField; + + @Override + public Iterator iterator() { + return fields.values().iterator(); + } + + public boolean isExtensible() { + return isExtensible; + } + + public Field getField(String name) { + Field field = fields.get(name); + return field == null && fields.containsKey("*") ? fields.get("*") : field; + } + + public Stream fields() { + return fields.values().stream(); + } + + NodeType addField(String name, NodeType... oneOfTypes) { + lastField = fields.computeIfAbsent(name, Field::new); + if (oneOfTypes != null && oneOfTypes.length > 0) { + lastField.oneOfTypes.addAll(Arrays.asList(oneOfTypes)); + } + return this; + } + + NodeType array() { + lastField.isArray = true; + return this; + } + + NodeType map() { + lastField.isMap = true; + return this; + } + + NodeType required() { + lastField.isRequired = true; + return this; + } + + NodeType addPatterndFields(NodeType... oneOfTypes) { + return addField("*", oneOfTypes); + } + + NodeType extensible() { + isExtensible = true; + return this; + } + + static { + OpenAPI + .addField("openapi", string).required() + .addField("info", Info).required() + .addField("servers", Server).array() + .addField("paths", Paths).required() + .addField("components", Components) + .addField("security", SecurityRequirement).array() + .addField("tags", Tag).array() + .addField("externalDocs", ExternalDocumentation) + .extensible(); + + Info + .addField("title", string).required() + .addField("description", string) + .addField("termsOfService", string) + .addField("contact", Contact) + .addField("license", License) + .addField("version", string).required() + .extensible(); + + Contact + .addField("name", string) + .addField("url", string) + .addField("email", string) + .extensible(); + + License + .addField("name", string).required() + .addField("url", string) + .extensible(); + + Server + .addField("url", string).required() + .addField("description", string) + .addField("variables", ServerVariable).map() + .extensible(); + + ServerVariable + .addField("enum", string).array() + .addField("default", string).required() + .addField("description", string) + .extensible(); + + Components + .addField("schemas", Schema).map() + .addField("responses", Response).map() + .addField("parameters", Parameter).map() + .addField("examples", Example).map() + .addField("requestBodies", RequestBody).map() + .addField("headers", Header).map() + .addField("securitySchemes", SecurityScheme).map() + .addField("links", Link).map() + .addField("callbacks", Callback).map() + .extensible(); + + Paths + .addPatterndFields(PathItem) + .extensible(); + + PathItem + .addField("$ref", string) + .addField("summary", string) + .addField("description", string) + .addField("get", Operation) + .addField("put", Operation) + .addField("post", Operation) + .addField("delete", Operation) + .addField("options", Operation) + .addField("head", Operation) + .addField("patch", Operation) + .addField("trace", Operation) + .addField("servers", Server).array() + .addField("parameters", Parameter, Reference).array() + .extensible(); + + Operation + .addField("tags", string).array() + .addField("summary", string) + .addField("description", string) + .addField("externalDocs", ExternalDocumentation) + .addField("operationId", string) + .addField("parameters", Parameter, Reference).array() + .addField("requestBody", RequestBody, Reference) + .addField("responses", Responses).required() + .addField("callbacks", Callback, Reference).map() + .addField("deprecated", bool) + .addField("security", SecurityRequirement).array() + .addField("servers", Server).array() + .extensible(); + + ExternalDocumentation + .addField("description", string) + .addField("url", string).required() + .extensible(); + + Parameter + .addField("name", string).required() + .addField("in", string).required() + .addField("description", string) + .addField("required", bool) + .addField("deprecated", bool) + .addField("allowEmptyValue", bool) + .addField("style", string) + .addField("explode", bool) + .addField("allowReserved", bool) + .addField("schema", Schema, Reference) + .addField("example") + .addField("examples", Example, Reference).map() + .addField("content", MediaType).map() + .extensible(); + + RequestBody + .addField("description", string) + .addField("content", MediaType).map().required() + .addField("required", bool) + .extensible(); + + MediaType + .addField("schema", Schema) + .addField("schema", Reference) + .addField("example") + .addField("examples", Example, Reference).map() + .addField("encoding", Encoding).map() + .extensible(); + + Encoding + .addField("contentType", string) + .addField("headers", Header, Reference).map() + .addField("style", string) + .addField("explode", bool) + .addField("allowReserved", bool) + .extensible(); + + Responses + .addField("default", Response, Reference) + .addPatterndFields(Response, Reference) + .extensible(); + + Response + .addField("description", string).required() + .addField("headers", Header, Reference).map() + .addField("content", MediaType).map() + .addField("links", Link, Reference).map() + .extensible(); + + Callback + .addPatterndFields(PathItem) + .extensible(); + + Example + .addField("summary", string) + .addField("description", string) + .addField("value") + .addField("externalValue", string) + .extensible(); + + Link + .addField("operationRef", string) + .addField("operationId", string) + .addField("parameters").map() + .addField("requestBody") + .addField("description", string) + .addField("server", Server) + .extensible(); + + Header + .addField("description", string) + .addField("required", bool) + .addField("deprecated", bool) + .addField("allowEmptyValue", bool) + .addField("style", string) + .addField("explode", bool) + .addField("allowReserved", bool) + .addField("schema", Schema) + .addField("schema", Reference) + .addField("example") + .addField("examples", Example, Reference).map() + .addField("content", MediaType).map() + .extensible(); + + Tag + .addField("name", string).required() + .addField("description", string) + .addField("externalDocs", ExternalDocumentation) + .extensible(); + + Reference + .addField("$ref", string).required(); + + Schema + .addField("title", string) + .addField("multipleOf", number) + .addField("maximum", number) + .addField("exclusiveMaximum", bool) + .addField("minimum", number) + .addField("exclusiveMinimum", bool) + .addField("maxLength", number) + .addField("minLength", number) + .addField("pattern", string) + .addField("maxItems", number) + .addField("minItems", number) + .addField("uniqueItems", bool) + .addField("maxProperties", number) + .addField("minProperties", number) + .addField("required", string).array() + .addField("enum").array() + .addField("type", string) + .addField("allOf", Schema, Reference).array() + .addField("oneOf", Schema, Reference).array() + .addField("anyOf", Schema, Reference).array() + .addField("not", Schema, Reference) + .addField("items", Schema, Reference) + .addField("properties", Schema, Reference).map() + .addField("additionalProperties", bool, Schema, Reference) + .addField("description", string) + .addField("format", string) + .addField("default") + .addField("nullable",bool) + .addField("discriminator", Discriminator) + .addField("readOnly", bool) + .addField("writeOnly", bool) + .addField("xml", XML) + .addField("externalDocs", ExternalDocumentation) + .addField("example") + .addField("deprecated", bool) + .extensible(); + + Discriminator + .addField("propertyName", string).required() + .addField("mapping", string).map(); + + XML + .addField("name", string) + .addField("namespace", string) + .addField("prefix", string) + .addField("attribute", bool) + .addField("wrapped", bool) + .extensible(); + + SecurityScheme + .addField("type", string).required() + .addField("description", string) + .addField("name", string) + .addField("in", string) + .addField("scheme", string) + .addField("bearerFormat", string) + .addField("flows", OAuthFlows) + .addField("openIdConnectUrl", string) + .extensible(); + + OAuthFlows + .addField("implicit", OAuthFlow) + .addField("password", OAuthFlow) + .addField("clientCredentials", OAuthFlow) + .addField("authorizationCode", OAuthFlow) + .extensible(); + + OAuthFlow + .addField("authorizationUrl", string) + .addField("tokenUrl", string) + .addField("refreshUrl", string) + .addField("scopes", string).map() + .extensible(); + + SecurityRequirement + .addPatterndFields(string).array(); + } +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java new file mode 100644 index 00000000000..8b1ad95cd95 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java @@ -0,0 +1,148 @@ +package fish.payara.microprofile.openapi.spec; + +import static java.util.Arrays.asList; +import static org.junit.Assert.fail; + +import java.util.EnumMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeType; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class OpenAPIValidator { + + private static final EnumMap> REQUIRED_FIELDS = new EnumMap<>(NodeType.class); + + private static Set requiredFields(NodeType type) { + return new HashSet<>(REQUIRED_FIELDS.computeIfAbsent(type, key -> key.fields() + .filter(field -> field.isRequired()) + .map(field -> field.getName()) + .collect(Collectors.toSet()))); + } + + public static void validate(JsonNode document) { + validate(NodeType.OpenAPI, document); + } + + public static void validate(NodeType expected, JsonNode actual) { + // do we have right type of JSON object? + if (expected == NodeType.string) { + assertJsonType(JsonNodeType.STRING, asList(expected), actual); + } else if (expected == NodeType.number) { + assertJsonType(JsonNodeType.NUMBER, asList(expected), actual); + } else if (expected == NodeType.bool) { + assertJsonType(JsonNodeType.BOOLEAN, asList(expected), actual); + } else { + assertJsonType(JsonNodeType.OBJECT, asList(expected), actual); + // are the fields ok? + ObjectNode obj = (ObjectNode) actual; + Iterator> iter = obj.fields(); + Set requiredFields = requiredFields(expected); + while (iter.hasNext()) { + Entry actualField = iter.next(); + String fieldName = actualField.getKey(); + if (fieldName.startsWith("x-")) { + if (!expected.isExtensible()) { + fail("Disallowed extension field `" + fieldName + "` for " + expected + " node in " + + describe(actual)); + } + } else { + requiredFields.remove(fieldName); + Field expectedField = expected.getField(fieldName); + if (expectedField == null) { + fail("Disallowed field `" + fieldName + "` for " + expected + " node in " + + describe(actual)); + } + validate(expectedField, actualField.getValue()); + } + } + if (!requiredFields.isEmpty()) { + fail("Missing required fields " + requiredFields + " for " + expected + " node in " + + describe(actual)); + } + } + } + + public static void validate(Field expected, JsonNode actual) { + if (expected.isArray()) { + assertJsonType(JsonNodeType.ARRAY, null, actual); + validateArray(expected, (ArrayNode) actual); + return; + } + if (expected.isMap()) { + assertJsonType(JsonNodeType.OBJECT, null, actual); + validateMap(expected, (ObjectNode) actual); + return; + } + validateTypes(expected, actual); + } + + private static void validateMap(Field expected, ObjectNode actual) { + for (JsonNode field : actual) { + validateTypes(expected, field); + } + // Note: the keys can be anything in general + // while certain maps might have special constraints these are not validated yet + } + + private static void validateArray(Field expected, ArrayNode actual) throws AssertionError { + for (JsonNode element : actual) { + validateTypes(expected, element); + } + } + + private static void validateTypes(Field expected, JsonNode actual) throws AssertionError { + if (expected.isAnyType()) { + return; // anything is fine, no validation required + } + Map errors = new LinkedHashMap<>(); + for (NodeType expectedElementType : expected) { + try { + validate(expectedElementType, actual); + return; // found a valid type + } catch (AssertionError e) { + errors.put(expectedElementType, e); + // try next + } + } + // none worked + if (errors.size() == 1) { + throw errors.values().iterator().next(); + } + StringBuilder message = new StringBuilder(); + message.append("Disallowed value for field `"+expected+"`: "+describe(actual)); + for (Entry error : errors.entrySet()) { + message.append("\n\nTrying ").append(error.getKey()).append(" gave:\n").append(error.getValue().getMessage()); + } + throw new AssertionError(message); + } + + private static void assertJsonType(JsonNodeType expectedJsonType, Iterable expected, JsonNode actual) { + if (actual.isNull()) { + if (expectedJsonType != JsonNodeType.OBJECT) { + fail("Disallowed null value for node of type" + expected + " in " + describe(actual)); + } + } else if (actual.getNodeType() != expectedJsonType) { + fail("Disallowed type " + actual.getNodeType() + " for " + expected + " in " + describe(actual)); + } + } + + private static String describe(JsonNode node) { + try { + ObjectMapper mapper = new ObjectMapper(); + Object json = mapper.readValue(node.toString(), Object.class); + return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json); + } catch (Exception e) { + return node.toString(); + } + } +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidatorTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidatorTest.java new file mode 100644 index 00000000000..396481ef372 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidatorTest.java @@ -0,0 +1,37 @@ +package fish.payara.microprofile.openapi.spec; + +import java.io.File; +import java.util.logging.Logger; + +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Test that should verify the validity of the {@link OpenAPIValidator} model by using it against some of the examples + * given in the specification. + */ +public class OpenAPIValidatorTest { + + private static final Logger LOGGER = Logger.getLogger(OpenAPIValidatorTest.class.getName()); + + @Test + public void verifyExamplesPassVerification() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + for (NodeType type : NodeType.values()) { + File exampleFile = new File("src/test/resources/" + type.name() + ".json"); + if (exampleFile.exists()) { + LOGGER.info("Verifying model for " + type); + JsonNode examples = mapper.readTree(exampleFile); + if (examples.isArray()) { + for (JsonNode example : examples) { + OpenAPIValidator.validate(type, example); + } + } else { + OpenAPIValidator.validate(type, examples); + } + } + } + } +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Callback.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Callback.json new file mode 100644 index 00000000000..3a74ac8969d --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Callback.json @@ -0,0 +1,21 @@ +{ + "http://notificationServer.com?transactionId={$request.body#/id}&email={$request.body#/email}": { + "post": { + "requestBody": { + "description": "Callback payload", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SomePayload" + } + } + } + }, + "responses": { + "200": { + "description": "webhook successfully processed and no retries will be performed" + } + } + } + } +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Components.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Components.json new file mode 100644 index 00000000000..788741659d2 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Components.json @@ -0,0 +1,87 @@ +{ + "schemas": { + "Category": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + } + }, + "Tag": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + } + } + }, + "parameters": { + "skipParam": { + "name": "skip", + "in": "query", + "description": "number of items to skip", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + "limitParam": { + "name": "limit", + "in": "query", + "description": "max records to return", + "required": true, + "schema" : { + "type": "integer", + "format": "int32" + } + } + }, + "responses": { + "NotFound": { + "description": "Entity not found." + }, + "IllegalInput": { + "description": "Illegal input for operation." + }, + "GeneralError": { + "description": "General Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GeneralError" + } + } + } + } + }, + "securitySchemes": { + "api_key": { + "type": "apiKey", + "name": "api_key", + "in": "header" + }, + "petstore_auth": { + "type": "oauth2", + "flows": { + "implicit": { + "authorizationUrl": "http://example.org/api/oauth/dialog", + "scopes": { + "write:pets": "modify pets in your account", + "read:pets": "read your pets" + } + } + } + } + } +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Contact.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Contact.json new file mode 100644 index 00000000000..4f96897c97d --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Contact.json @@ -0,0 +1,5 @@ +{ + "name": "API Support", + "url": "http://www.example.com/support", + "email": "support@example.com" +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Discriminator.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Discriminator.json new file mode 100644 index 00000000000..5fe54bf55d3 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Discriminator.json @@ -0,0 +1,7 @@ +{ + "propertyName": "pet_type", + "mapping": { + "dog": "#/components/schemas/Dog", + "monster": "https://gigantic-server.com/schemas/Monster/schema.json" + } +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Encoding.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Encoding.json new file mode 100644 index 00000000000..4b6a402fa5f --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Encoding.json @@ -0,0 +1,16 @@ +[ +{ + "contentType": "application/xml; charset=utf-8" +}, +{ + "contentType": "image/png, image/jpeg", + "headers": { + "X-Rate-Limit-Limit": { + "description": "The number of allowed requests in the current period", + "schema": { + "type": "integer" + } + } + } +} +] \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Example.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Example.json new file mode 100644 index 00000000000..23e45c2942c --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Example.json @@ -0,0 +1,12 @@ +[ +{ + "summary": "A foo example", + "value": { + "foo": "bar" + } +}, +{ + "summary": "This is a text example", + "externalValue": "http://foo.bar/examples/address-example.txt" +} +] \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/ExternalDocumentation.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/ExternalDocumentation.json new file mode 100644 index 00000000000..aad9ff4f33c --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/ExternalDocumentation.json @@ -0,0 +1,4 @@ +{ + "description": "Find more info here", + "url": "https://example.com" +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Header.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Header.json new file mode 100644 index 00000000000..3739e098798 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Header.json @@ -0,0 +1,6 @@ +{ + "description": "The number of allowed requests in the current period", + "schema": { + "type": "integer" + } +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Info.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Info.json new file mode 100644 index 00000000000..e9073d51b75 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Info.json @@ -0,0 +1,15 @@ +{ + "title": "Sample Pet Store App", + "description": "This is a sample server for a pet store.", + "termsOfService": "http://example.com/terms/", + "contact": { + "name": "API Support", + "url": "http://www.example.com/support", + "email": "support@example.com" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "1.0.1" +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/License.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/License.json new file mode 100644 index 00000000000..6ccb0fa39b7 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/License.json @@ -0,0 +1,4 @@ +{ + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Link.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Link.json new file mode 100644 index 00000000000..03ce9079eae --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Link.json @@ -0,0 +1,14 @@ +[ +{ + "operationRef": "#/paths/~12.0~1repositories~1{username}/get", + "parameters": { + "username": "$response.body#/username" + } +}, +{ + "operationRef": "https://na2.gigantic-server.com/#/paths/~12.0~1repositories~1{username}/get", + "parameters": { + "username": "$response.body#/username" + } +} +] \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/MediaType.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/MediaType.json new file mode 100644 index 00000000000..51d45f5e80c --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/MediaType.json @@ -0,0 +1,31 @@ +{ + "schema": { + "$ref": "#/components/schemas/Pet" + }, + "examples": { + "cat" : { + "summary": "An example of a cat", + "value": + { + "name": "Fluffy", + "petType": "Cat", + "color": "White", + "gender": "male", + "breed": "Persian" + } + }, + "dog": { + "summary": "An example of a dog with a cat's name", + "value" : { + "name": "Puma", + "petType": "Dog", + "color": "Black", + "gender": "Female", + "breed": "Mixed" + } + }, + "frog": { + "$ref": "#/components/examples/frog-example" + } + } +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/OAuthFlows.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/OAuthFlows.json new file mode 100644 index 00000000000..9cb92c284f8 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/OAuthFlows.json @@ -0,0 +1,17 @@ +{ + "implicit": { + "authorizationUrl": "https://example.com/api/oauth/dialog", + "scopes": { + "write:pets": "modify pets in your account", + "read:pets": "read your pets" + } + }, + "authorizationCode": { + "authorizationUrl": "https://example.com/api/oauth/dialog", + "tokenUrl": "https://example.com/api/oauth/token", + "scopes": { + "write:pets": "modify pets in your account", + "read:pets": "read your pets" + } + } +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Operation.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Operation.json new file mode 100644 index 00000000000..9d5996ba488 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Operation.json @@ -0,0 +1,62 @@ +{ + "tags": [ + "pet" + ], + "summary": "Updates a pet in the store with form data", + "operationId": "updatePetWithForm", + "parameters": [ + { + "name": "petId", + "in": "path", + "description": "ID of pet that needs to be updated", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "type": "object", + "properties": { + "name": { + "description": "Updated name of the pet", + "type": "string" + }, + "status": { + "description": "Updated status of the pet", + "type": "string" + } + }, + "required": ["status"] + } + } + } + }, + "responses": { + "200": { + "description": "Pet updated.", + "content": { + "application/json": {}, + "application/xml": {} + } + }, + "405": { + "description": "Invalid input", + "content": { + "application/json": {}, + "application/xml": {} + } + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Parameter.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Parameter.json new file mode 100644 index 00000000000..bfae151ff49 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Parameter.json @@ -0,0 +1,73 @@ +[ +{ + "name": "token", + "in": "header", + "description": "token to be passed as a header", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + } + }, + "style": "simple" +}, +{ + "name": "username", + "in": "path", + "description": "username to fetch", + "required": true, + "schema": { + "type": "string" + } +}, +{ + "name": "id", + "in": "query", + "description": "ID of the object to fetch", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "style": "form", + "explode": true +}, +{ + "in": "query", + "name": "freeForm", + "schema": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "style": "form" +}, +{ + "in": "query", + "name": "coordinates", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "lat", + "long" + ], + "properties": { + "lat": { + "type": "number" + }, + "long": { + "type": "number" + } + } + } + } + } +} +] \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/PathItem.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/PathItem.json new file mode 100644 index 00000000000..a563f18c88e --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/PathItem.json @@ -0,0 +1,47 @@ +{ + "get": { + "description": "Returns pets based on ID", + "summary": "Find pets by ID", + "operationId": "getPetsById", + "responses": { + "200": { + "description": "pet response", + "content": { + "*/*": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Pet" + } + } + } + } + }, + "default": { + "description": "error payload", + "content": { + "text/html": { + "schema": { + "$ref": "#/components/schemas/ErrorModel" + } + } + } + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of pet to use", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "style": "simple" + } + ] +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Paths.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Paths.json new file mode 100644 index 00000000000..7576cc58e2f --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Paths.json @@ -0,0 +1,22 @@ +{ + "/pets": { + "get": { + "description": "Returns all pets from the system that the user has access to", + "responses": { + "200": { + "description": "A list of pets.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/pet" + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Reference.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Reference.json new file mode 100644 index 00000000000..82725862321 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Reference.json @@ -0,0 +1,11 @@ +[ +{ + "$ref": "#/components/schemas/Pet" +}, +{ + "$ref": "Pet.json" +}, +{ + "$ref": "definitions.json#/Pet" +} +] \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/RequestBody.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/RequestBody.json new file mode 100644 index 00000000000..5fc8d1c3af5 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/RequestBody.json @@ -0,0 +1,58 @@ +[ +{ + "description": "user to add to the system", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + }, + "examples": { + "user" : { + "summary": "User Example", + "externalValue": "http://foo.bar/examples/user-example.json" + } + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/User" + }, + "examples": { + "user" : { + "summary": "User example in XML", + "externalValue": "http://foo.bar/examples/user-example.xml" + } + } + }, + "text/plain": { + "examples": { + "user" : { + "summary": "User example in Plain text", + "externalValue": "http://foo.bar/examples/user-example.txt" + } + } + }, + "*/*": { + "examples": { + "user" : { + "summary": "User example in other format", + "externalValue": "http://foo.bar/examples/user-example.whatever" + } + } + } + } +}, +{ + "description": "user to add to the system", + "content": { + "text/plain": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } +} +] \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Response.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Response.json new file mode 100644 index 00000000000..6256be29d37 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Response.json @@ -0,0 +1,58 @@ +[ +{ + "description": "A complex object array response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VeryComplexType" + } + } + } + } +}, +{ + "description": "A simple string response", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } +}, +{ + "description": "A simple string response", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + }, + "headers": { + "X-Rate-Limit-Limit": { + "description": "The number of allowed requests in the current period", + "schema": { + "type": "integer" + } + }, + "X-Rate-Limit-Remaining": { + "description": "The number of remaining requests in the current period", + "schema": { + "type": "integer" + } + }, + "X-Rate-Limit-Reset": { + "description": "The number of seconds left in the current period", + "schema": { + "type": "integer" + } + } + } +}, +{ + "description": "object created" +} +] \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Responses.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Responses.json new file mode 100644 index 00000000000..d5fa9616965 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Responses.json @@ -0,0 +1,22 @@ +{ + "200": { + "description": "a pet to be returned", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pet" + } + } + } + }, + "default": { + "description": "Unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorModel" + } + } + } + } +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Schema.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Schema.json new file mode 100644 index 00000000000..00aed5b9228 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Schema.json @@ -0,0 +1,159 @@ +[ +{ + "type": "string", + "format": "email" +}, +{ + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + }, + "address": { + "$ref": "#/components/schemas/Address" + }, + "age": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } +}, +{ + "type": "object", + "additionalProperties": { + "type": "string" + } +}, +{ + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/ComplexModel" + } +}, +{ + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "example": { + "name": "Puma", + "id": 1 + } +}, +{ + "type": "object", + "required": [ + "message", + "code" + ], + "properties": { + "message": { + "type": "string" + }, + "code": { + "type": "integer", + "minimum": 100, + "maximum": 600 + } + } +}, +{ + "allOf": [ + { + "$ref": "#/components/schemas/ErrorModel" + }, + { + "type": "object", + "required": [ + "rootCause" + ], + "properties": { + "rootCause": { + "type": "string" + } + } + } + ] +}, +{ + "type": "object", + "discriminator": { + "propertyName": "petType" + }, + "properties": { + "name": { + "type": "string" + }, + "petType": { + "type": "string" + } + }, + "required": [ + "name", + "petType" + ] +}, +{ + "description": "A representation of a cat. Note that `Cat` will be used as the discriminator value.", + "allOf": [ + { + "$ref": "#/components/schemas/Pet" + }, + { + "type": "object", + "properties": { + "huntingSkill": { + "type": "string", + "description": "The measured skill for hunting", + "default": "lazy", + "enum": [ + "clueless", + "lazy", + "adventurous", + "aggressive" + ] + } + }, + "required": [ + "huntingSkill" + ] + } + ] +}, +{ + "description": "A representation of a dog. Note that `Dog` will be used as the discriminator value.", + "allOf": [ + { + "$ref": "#/components/schemas/Pet" + }, + { + "type": "object", + "properties": { + "packSize": { + "type": "integer", + "format": "int32", + "description": "the size of the pack the dog is from", + "default": 0, + "minimum": 0 + } + }, + "required": [ + "packSize" + ] + } + ] +} +] \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/SecurityRequirement.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/SecurityRequirement.json new file mode 100644 index 00000000000..dba923676c7 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/SecurityRequirement.json @@ -0,0 +1,11 @@ +[ +{ + "api_key": [] +}, +{ + "petstore_auth": [ + "write:pets", + "read:pets" + ] +} +] \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/SecurityScheme.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/SecurityScheme.json new file mode 100644 index 00000000000..99fe7035acd --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/SecurityScheme.json @@ -0,0 +1,28 @@ +[ +{ + "type": "http", + "scheme": "basic" +}, +{ + "type": "apiKey", + "name": "api_key", + "in": "header" +}, +{ + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT" +}, +{ + "type": "oauth2", + "flows": { + "implicit": { + "authorizationUrl": "https://example.com/api/oauth/dialog", + "scopes": { + "write:pets": "modify pets in your account", + "read:pets": "read your pets" + } + } + } +} +] \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Server.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Server.json new file mode 100644 index 00000000000..f47156f7a80 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Server.json @@ -0,0 +1,4 @@ +{ + "url": "https://development.gigantic-server.com/v1", + "description": "Development server" +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/ServerVariable.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/ServerVariable.json new file mode 100644 index 00000000000..5c05e2a75d0 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/ServerVariable.json @@ -0,0 +1,10 @@ +[ +{ + "default": "demo", + "description": "this value is assigned by the service provider, in this example `gigantic-server.com`" +}, +{ + "enum": ["8443", "443" ], + "default": "8443" +} +] \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Tag.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Tag.json new file mode 100644 index 00000000000..1f94f625999 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/Tag.json @@ -0,0 +1,4 @@ +{ + "name": "pet", + "description": "Pets operations" +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/XML.json b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/XML.json new file mode 100644 index 00000000000..b30d2e7dcb1 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/resources/XML.json @@ -0,0 +1,10 @@ +[ +{ + "namespace": "http://example.com/schema/sample", + "prefix": "sample" +}, +{ + "name": "aliens", + "wrapped": true +} +] \ No newline at end of file From cca2a769839c07a0e697bc7caa2e472ea34b98c2 Mon Sep 17 00:00:00 2001 From: Jonathan Coustick Date: Fri, 15 Mar 2019 17:39:11 +0000 Subject: [PATCH 037/108] PAYARA-3682 Increase sleep time to ensure new manifest has later timestamp --- appserver/appclient/client/acc-standalone/fixup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appserver/appclient/client/acc-standalone/fixup.xml b/appserver/appclient/client/acc-standalone/fixup.xml index 0b25c78d07f..abd1c43e9e1 100644 --- a/appserver/appclient/client/acc-standalone/fixup.xml +++ b/appserver/appclient/client/acc-standalone/fixup.xml @@ -111,7 +111,7 @@ manifest file, so we need to explicitly touch it after updating the manifest. --> - + From 5d0f627ee2ebacf71fc95484ef11d9221b7d809c Mon Sep 17 00:00:00 2001 From: Steve Millidge Date: Sat, 16 Mar 2019 20:02:29 +0000 Subject: [PATCH 038/108] PAYARA-3686 unable to save the Default Principal in the Sercurity Service page of the admin console --- .../common/src/main/resources/security/securityAttrs.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appserver/admingui/common/src/main/resources/security/securityAttrs.inc b/appserver/admingui/common/src/main/resources/security/securityAttrs.inc index 603fc08f567..f506d5cc30a 100644 --- a/appserver/admingui/common/src/main/resources/security/securityAttrs.inc +++ b/appserver/admingui/common/src/main/resources/security/securityAttrs.inc @@ -66,10 +66,10 @@ /> - + - + From e68de86b4b3f8fb84013be8fdb9fdf1a09d00eea Mon Sep 17 00:00:00 2001 From: arjantijms Date: Mon, 18 Mar 2019 12:20:56 +0100 Subject: [PATCH 039/108] PAYARA-3684 Addressing feedback, disambiguated BaseRealm name --- .../auth/realm/{BaseRealm.java => BaseStateRealm.java} | 4 ++-- .../java/com/sun/enterprise/security/auth/realm/Realm.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/{BaseRealm.java => BaseStateRealm.java} (98%) diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseStateRealm.java similarity index 98% rename from nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseRealm.java rename to nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseStateRealm.java index bab835598e7..bedec008f4c 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseRealm.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseStateRealm.java @@ -54,7 +54,7 @@ * @author Arjan Tijms * */ -public abstract class BaseRealm extends AbstractRealm implements Comparable { +public abstract class BaseStateRealm extends AbstractRealm implements Comparable { public static final String PARAM_GROUP_MAPPING = "group-mapping"; @@ -79,7 +79,7 @@ public abstract class BaseRealm extends AbstractRealm implements Comparable { +public abstract class Realm extends BaseStateRealm implements Comparable { protected static final Logger _logger = SecurityLoggerInfo.getLogger(); private static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(Realm.class); From 9da68139bcc226ee67f1e60dd782040110a7936f Mon Sep 17 00:00:00 2001 From: arjantijms Date: Mon, 18 Mar 2019 12:48:37 +0000 Subject: [PATCH 040/108] PAYARA-3684 renamed to AbstractStatefulRealm after chat --- .../realm/{BaseStateRealm.java => AbstractStatefulRealm.java} | 4 ++-- .../java/com/sun/enterprise/security/auth/realm/Realm.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/{BaseStateRealm.java => AbstractStatefulRealm.java} (98%) diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseStateRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AbstractStatefulRealm.java similarity index 98% rename from nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseStateRealm.java rename to nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AbstractStatefulRealm.java index bedec008f4c..7645f578f82 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/BaseStateRealm.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AbstractStatefulRealm.java @@ -54,7 +54,7 @@ * @author Arjan Tijms * */ -public abstract class BaseStateRealm extends AbstractRealm implements Comparable { +public abstract class AbstractStatefulRealm extends AbstractRealm implements Comparable { public static final String PARAM_GROUP_MAPPING = "group-mapping"; @@ -79,7 +79,7 @@ public abstract class BaseStateRealm extends AbstractRealm implements Comparable * The default the constructor creates a realm which will later be initialized, * either from properties or by deserializing. */ - protected BaseStateRealm() { + protected AbstractStatefulRealm() { contextProperties = new Properties(); } diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java index f8f9a16ce94..d8db7c8b8fb 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java @@ -73,7 +73,7 @@ * @see java.security.Principal */ @Contract -public abstract class Realm extends BaseStateRealm implements Comparable { +public abstract class Realm extends AbstractStatefulRealm implements Comparable { protected static final Logger _logger = SecurityLoggerInfo.getLogger(); private static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(Realm.class); From 068b44d6ba00d2dffc80d0f350b32e489a980e70 Mon Sep 17 00:00:00 2001 From: arjantijms Date: Mon, 18 Mar 2019 17:12:30 +0100 Subject: [PATCH 041/108] PAYARA-3684 Addressing feedback - changes too small to justify cr update --- .../enterprise/security/auth/login/LDAPLoginModule.java | 3 ++- .../security/auth/login/common/PasswordCredential.java | 9 +++++---- .../security/auth/realm/GroupNotEmptyException.java | 4 ++-- .../security/auth/realm/InvalidOperationException.java | 4 ++-- .../security/auth/realm/NoSuchUserException.java | 4 ++-- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LDAPLoginModule.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LDAPLoginModule.java index 41239720375..35589c17a53 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LDAPLoginModule.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/LDAPLoginModule.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.login; import static com.sun.enterprise.security.auth.realm.ldap.LDAPRealm.MODE_FIND_BIND; @@ -73,6 +73,7 @@ * are taken as group names in which the user has membership. If no entries are found, the group membership is empty. * * + * */ public class LDAPLoginModule extends BasePasswordLoginModule { diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/PasswordCredential.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/PasswordCredential.java index 9f151d94fa0..f8547b61dee 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/PasswordCredential.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/login/common/PasswordCredential.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.login.common; import java.util.Arrays; @@ -46,12 +46,13 @@ * This class holds the user password for the shared password realm and the realm name. This credential is added as a * private credential to the JAAS subject. */ + public class PasswordCredential { private String username; private char[] password; private String realm; private boolean readOnly = false; - + // target_name is filled in by the SecSecurityServer interceptor // only when a CSIv2 GSSUP authenticator is received. private byte[] target_name = {}; @@ -73,11 +74,11 @@ public PasswordCredential(String user, char[] password, String realm) { if (this.username == null) { this.username = ""; } - + if (this.password == null) { this.password = new char[] {}; } - + if (this.realm == null) { this.realm = ""; } diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupNotEmptyException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupNotEmptyException.java index 41607f13e10..07702d020d9 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupNotEmptyException.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/GroupNotEmptyException.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2019] [Payara Foundation and/or its affiliates] + package com.sun.enterprise.security.auth.realm; /** @@ -46,7 +46,7 @@ * @author Harpreet Singh */ public class GroupNotEmptyException extends Exception { - + private static final long serialVersionUID = 873043596300984484L; /** diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/InvalidOperationException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/InvalidOperationException.java index 9c9cfe09b8c..5adbeaedc00 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/InvalidOperationException.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/InvalidOperationException.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm; /** @@ -47,7 +47,7 @@ * @author Harpreet Singh */ public class InvalidOperationException extends Exception { - + private static final long serialVersionUID = 1124276549235903088L; /** diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchUserException.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchUserException.java index d2e6256ba76..01185d4dac1 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchUserException.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/NoSuchUserException.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.auth.realm; /** @@ -46,7 +46,7 @@ * @author Harish Prabandham */ public class NoSuchUserException extends Exception { - + private static final long serialVersionUID = -4061500111336089813L; /** From 4076aa9b2d2e2b2cf59108f3efe264f14282cf80 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Mon, 18 Mar 2019 17:39:15 +0100 Subject: [PATCH 042/108] PAYARA-3466 fixed serialisation of extentions and maps with properties --- .../openapi/impl/model/ExtensibleImpl.java | 14 ++++- .../openapi/impl/model/ExtensibleTreeMap.java | 60 +++++++++++++++++-- .../model/responses/APIResponsesImpl.java | 3 - 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index 44989012b07..dd7207ee4de 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -46,6 +46,7 @@ import java.lang.reflect.Modifier; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.logging.Logger; import org.eclipse.microprofile.openapi.annotations.extensions.Extension; @@ -71,19 +72,26 @@ public Map getExtensions() { @Override public T addExtension(String name, Object value) { if (value != null) { - extensions.put(name, value); + extensions.put(extensionName(name), value); } return (T) this; } @Override public void removeExtension(String name) { - extensions.remove(name); + extensions.remove(extensionName(name)); } @Override public void setExtensions(Map extensions) { - this.extensions = extensions; + this.extensions.clear(); + for (Entry entry : extensions.entrySet()) { + this.extensions.put(extensionName(entry.getKey()), entry.getValue()); + } + } + + public static String extensionName(String name) { + return name.startsWith("x-") ? name : "x-" + name; } public static void merge(Extension from, Extensible to, boolean override) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java index 77c65793f9b..b0fabf39b7d 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java @@ -1,13 +1,24 @@ package fish.payara.microprofile.openapi.impl.model; +import static fish.payara.microprofile.openapi.impl.model.ExtensibleImpl.extensionName; + +import java.io.IOException; +import java.lang.reflect.ParameterizedType; import java.util.LinkedHashMap; import java.util.Map; import java.util.TreeMap; +import java.util.Map.Entry; import org.eclipse.microprofile.openapi.models.Extensible; +import org.eclipse.microprofile.openapi.models.Reference; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +@JsonSerialize(using = ExtensibleTreeMap.ExtensibleTreeMapSerializer.class) public abstract class ExtensibleTreeMap> extends TreeMap implements Extensible { @@ -29,20 +40,61 @@ public final Map getExtensions() { @Override public final void setExtensions(Map extensions) { - this.extensions = extensions; + this.extensions.clear(); + for (Entry entry : extensions.entrySet()) { + this.extensions.put(extensionName(entry.getKey()), entry.getValue()); + } } @SuppressWarnings("unchecked") @Override public final T addExtension(String name, Object value) { - if (value != null && name.startsWith("x-")) { - this.extensions.put(name, value); + if (value != null) { + this.extensions.put(extensionName(name), value); } return (T) this; } @Override public final void removeExtension(String name) { - this.extensions.remove(name); + this.extensions.remove(extensionName(name)); + } + + /** + * Custom {@link JsonSerializer} that adds both the extended {@link TreeMap} entries as well as the + * {@link ExtensibleTreeMap#extensions} map to the output object unless the value represents a {@link Reference} in + * which case only the {@link Reference#getRef()} is added. + */ + static class ExtensibleTreeMapSerializer extends JsonSerializer> { + + @Override + public void serialize(ExtensibleTreeMap value, JsonGenerator gen, SerializerProvider serializers) + throws IOException { + if (value instanceof Reference) { + Reference reference = (Reference) value; + String ref = reference.getRef(); + if (ref != null) { + gen.writeStartObject(value); + gen.writeFieldName("$ref"); + gen.writeString(ref); + gen.writeEndObject(); + return; // if this is a ref no extensions or map entries are relevant + } + } + gen.writeStartObject(value); + ParameterizedType mapType = (ParameterizedType) value.getClass().getGenericSuperclass(); + Class valueType = (Class) mapType.getActualTypeArguments()[0]; + JsonSerializer valueSerializer = serializers.findValueSerializer(valueType); + for (Map.Entry entry : value.entrySet()) { + gen.writeFieldName(entry.getKey()); + valueSerializer.serialize(entry.getValue(), gen, serializers); + } + for (Map.Entry extension : value.getExtensions().entrySet()) { + gen.writeFieldName(extension.getKey()); + Object extensionValue = extension.getValue(); + serializers.findValueSerializer(extensionValue.getClass()).serialize(extensionValue, gen, serializers); + } + gen.writeEndObject(); + } } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java index 99fd4de5066..e1ea4150c79 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java @@ -41,7 +41,6 @@ import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.isAnnotationNull; -import java.util.HashMap; import java.util.Map; import org.eclipse.microprofile.openapi.models.media.Schema; @@ -55,8 +54,6 @@ public class APIResponsesImpl extends ExtensibleTreeMap extensions = new HashMap<>(); - public APIResponsesImpl() { super(); } From cbcd0318831f9256cd7080155729076697dd6945 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Mon, 18 Mar 2019 17:40:35 +0100 Subject: [PATCH 043/108] PAYARA-3466 extracted base class for example app based tests with document validation, added more tests --- .../impl/model/ModelSerialisationTest.java | 4 +-- .../rule/ApplicationProcessedDocument.java | 31 +++++++++++++------ .../openapi/spec/OpenAPIValidator.java | 10 ++++-- .../test/app/OpenAPIApplicationTest.java | 31 +++++++++++++++++++ .../openapi/test/app/TestApplication.java | 14 --------- .../test/app/application/ResponseTest.java | 22 +++---------- .../test/app/application/RootPathTest.java | 19 ++---------- .../openapi/test/app/data/TestComponent.java | 20 ++---------- 8 files changed, 69 insertions(+), 82 deletions(-) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenAPIApplicationTest.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java index b1a0b93ab9c..525bbfd60c3 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java @@ -29,7 +29,7 @@ public class ModelSerialisationTest { @Test public void callbackWithRef() { - assertValid(NodeType.Callback, newCallbackRef("#/components/schemas/SomePayload")); + assertValid(NodeType.Reference, newCallbackRef("#/components/schemas/SomePayload")); } @Test @@ -39,7 +39,7 @@ public void callbackWithPathItem() { @Test public void callbackWithExtension() { - assertValid(NodeType.Callback, newCallbackRef("#/components/schemas/SomePayload") + assertValid(NodeType.Callback, newCallback("foo", newPathItemRef("#bar")) .addExtension("hello", "world")); } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java index 09e7befb1bf..315b8a71a74 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java @@ -44,22 +44,33 @@ import fish.payara.microprofile.openapi.impl.processor.BaseProcessor; import fish.payara.microprofile.openapi.resource.classloader.ApplicationClassLoader; import fish.payara.microprofile.openapi.test.app.TestApplication; -import fish.payara.microprofile.openapi.test.app.data.TestComponent; -import java.net.MalformedURLException; import java.net.URL; +import java.util.HashSet; + +import org.eclipse.microprofile.openapi.models.OpenAPI; + import static java.util.Arrays.asList; -import static java.util.Collections.singleton; +import static org.junit.Assert.fail; -public class ApplicationProcessedDocument extends OpenAPIImpl { +public class ApplicationProcessedDocument { - public ApplicationProcessedDocument() throws MalformedURLException { - // Apply base processor - new BaseProcessor(asList(new URL("http://localhost:8080/testlocation_123"))).process(this, null); + public static OpenAPI createDocument(Class... extraClasses) { + try { + OpenAPIImpl document = new OpenAPIImpl(); + // Apply base processor + new BaseProcessor(asList(new URL("http://localhost:8080/testlocation_123"))).process(document, null); - ApplicationClassLoader appClassLoader = new ApplicationClassLoader(new TestApplication(), singleton(TestComponent.class)); + ApplicationClassLoader appClassLoader = new ApplicationClassLoader(new TestApplication(), + new HashSet<>(asList(extraClasses))); - // Apply application processor - new ApplicationProcessor(appClassLoader.getApplicationClasses()).process(this, null); + // Apply application processor + new ApplicationProcessor(appClassLoader.getApplicationClasses()).process(document, null); + return document; + } catch (Exception ex) { + ex.printStackTrace(); + fail("Failed to build document."); + return null; + } } } \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java index 8b1ad95cd95..e9445a6ad7a 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java @@ -52,14 +52,14 @@ public static void validate(NodeType expected, JsonNode actual) { String fieldName = actualField.getKey(); if (fieldName.startsWith("x-")) { if (!expected.isExtensible()) { - fail("Disallowed extension field `" + fieldName + "` for " + expected + " node in " + fail("Disallowed extension " + describeField(fieldName) + " for " + expected + " node in " + describe(actual)); } } else { requiredFields.remove(fieldName); Field expectedField = expected.getField(fieldName); if (expectedField == null) { - fail("Disallowed field `" + fieldName + "` for " + expected + " node in " + fail("Disallowed " + describeField(fieldName) + " for " + expected + " node in " + describe(actual)); } validate(expectedField, actualField.getValue()); @@ -119,7 +119,7 @@ private static void validateTypes(Field expected, JsonNode actual) throws Assert throw errors.values().iterator().next(); } StringBuilder message = new StringBuilder(); - message.append("Disallowed value for field `"+expected+"`: "+describe(actual)); + message.append("Disallowed value for " + describeField(expected.getName()) + ": " + describe(actual)); for (Entry error : errors.entrySet()) { message.append("\n\nTrying ").append(error.getKey()).append(" gave:\n").append(error.getValue().getMessage()); } @@ -145,4 +145,8 @@ private static String describe(JsonNode node) { return node.toString(); } } + + private static String describeField(String fieldName) { + return "*".equals(fieldName) ? "patterned field" : "field `"+fieldName + "`"; + } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenAPIApplicationTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenAPIApplicationTest.java new file mode 100644 index 00000000000..3bacecc16b9 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenAPIApplicationTest.java @@ -0,0 +1,31 @@ +package fish.payara.microprofile.openapi.test.app; + +import static org.junit.Assert.assertNotNull; + +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import fish.payara.microprofile.openapi.impl.rest.app.provider.ObjectMapperFactory; +import fish.payara.microprofile.openapi.resource.rule.ApplicationProcessedDocument; +import fish.payara.microprofile.openapi.spec.OpenAPIValidator; + +public abstract class OpenAPIApplicationTest { + + private static final ObjectMapper JSON_MAPPER = ObjectMapperFactory.createJson(); + + protected OpenAPI document; + + @Before + public void createDocument() { + document = ApplicationProcessedDocument.createDocument(getClass()); + } + + @Test + public void documentIsValid() { + assertNotNull(document); + OpenAPIValidator.validate(JSON_MAPPER.valueToTree(document)); + } +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/TestApplication.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/TestApplication.java index ab28ceecf20..cdf34aa3ec6 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/TestApplication.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/TestApplication.java @@ -39,24 +39,10 @@ */ package fish.payara.microprofile.openapi.test.app; -import java.util.HashSet; -import java.util.Set; - import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; -import fish.payara.microprofile.openapi.test.app.application.ResponseTest; -import fish.payara.microprofile.openapi.test.app.application.RootPathTest; - @ApplicationPath("/test") public class TestApplication extends Application { - @Override - public Set> getClasses() { - Set> classes = new HashSet<>(); - classes.add(RootPathTest.class); - classes.add(ResponseTest.class); - return classes; - } - } \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java index 550efd49ce0..b03cc806fd7 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java @@ -44,7 +44,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -53,34 +52,21 @@ import org.eclipse.microprofile.openapi.annotations.media.Content; import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.eclipse.microprofile.openapi.models.OpenAPI; import org.eclipse.microprofile.openapi.models.responses.APIResponses; -import org.junit.BeforeClass; import org.junit.Test; -import fish.payara.microprofile.openapi.resource.rule.ApplicationProcessedDocument; +import fish.payara.microprofile.openapi.test.app.OpenAPIApplicationTest; /** * A resource to test that various response types are mapped properly. */ @Path("/response") @Produces({ APPLICATION_JSON, APPLICATION_XML }) -public class ResponseTest { - - public transient static OpenAPI document; - - @BeforeClass - public static void createDocument() { - try { - document = new ApplicationProcessedDocument(); - } catch (Exception ex) { - ex.printStackTrace(); - fail("Failed to build document."); - } - } +public class ResponseTest extends OpenAPIApplicationTest { @GET - @APIResponse(responseCode = "200", content = @Content(schema = @Schema(description = "hello!"))) + @APIResponse(responseCode = "200", description = "success", + content = @Content(schema = @Schema(description = "hello!"))) @APIResponse(responseCode = "400", description = "error") public String getInheritedMediaType() { return null; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java index 0e4b48f0b68..9bace938645 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java @@ -41,34 +41,19 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; import javax.ws.rs.GET; import javax.ws.rs.Path; -import org.eclipse.microprofile.openapi.models.OpenAPI; -import org.junit.BeforeClass; import org.junit.Test; -import fish.payara.microprofile.openapi.resource.rule.ApplicationProcessedDocument; +import fish.payara.microprofile.openapi.test.app.OpenAPIApplicationTest; /** * A resource to test that a resource at the context root is mapped correctly. */ @Path("") -public class RootPathTest { - - public transient static OpenAPI document; - - @BeforeClass - public static void createDocument() { - try { - document = new ApplicationProcessedDocument(); - } catch (Exception ex) { - ex.printStackTrace(); - fail("Failed to build document."); - } - } +public class RootPathTest extends OpenAPIApplicationTest { @GET public String getRoot() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java index 0e65f086af8..073e9092340 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java @@ -40,31 +40,16 @@ package fish.payara.microprofile.openapi.test.app.data; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; import org.eclipse.microprofile.openapi.annotations.media.Schema; -import org.eclipse.microprofile.openapi.models.OpenAPI; -import org.junit.BeforeClass; import org.junit.Test; -import fish.payara.microprofile.openapi.resource.rule.ApplicationProcessedDocument; +import fish.payara.microprofile.openapi.test.app.OpenAPIApplicationTest; /** * A test to check that schema objects without a @Schema annotation at the top are created. */ -public class TestComponent { - - public transient static OpenAPI document; - - @BeforeClass - public static void createDocument() { - try { - document = new ApplicationProcessedDocument(); - } catch (Exception ex) { - ex.printStackTrace(); - fail("Failed to build document."); - } - } +public class TestComponent extends OpenAPIApplicationTest { @Schema(description = "Test property") private int property; @@ -74,5 +59,4 @@ public void pojoCreationTest() { assertNotNull(document.getComponents().getSchemas().get("TestComponent")); } - } \ No newline at end of file From 2d2af207e2bd44723a897fc45d9ccfad053029a6 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Mon, 18 Mar 2019 17:39:15 +0100 Subject: [PATCH 044/108] PAYARA-3466 fixed serialisation of extentions and maps with properties --- .../openapi/impl/model/ExtensibleImpl.java | 14 ++++- .../openapi/impl/model/ExtensibleTreeMap.java | 60 +++++++++++++++++-- .../model/responses/APIResponsesImpl.java | 3 - 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index 44989012b07..dd7207ee4de 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -46,6 +46,7 @@ import java.lang.reflect.Modifier; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.logging.Logger; import org.eclipse.microprofile.openapi.annotations.extensions.Extension; @@ -71,19 +72,26 @@ public Map getExtensions() { @Override public T addExtension(String name, Object value) { if (value != null) { - extensions.put(name, value); + extensions.put(extensionName(name), value); } return (T) this; } @Override public void removeExtension(String name) { - extensions.remove(name); + extensions.remove(extensionName(name)); } @Override public void setExtensions(Map extensions) { - this.extensions = extensions; + this.extensions.clear(); + for (Entry entry : extensions.entrySet()) { + this.extensions.put(extensionName(entry.getKey()), entry.getValue()); + } + } + + public static String extensionName(String name) { + return name.startsWith("x-") ? name : "x-" + name; } public static void merge(Extension from, Extensible to, boolean override) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java index 77c65793f9b..b0fabf39b7d 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleTreeMap.java @@ -1,13 +1,24 @@ package fish.payara.microprofile.openapi.impl.model; +import static fish.payara.microprofile.openapi.impl.model.ExtensibleImpl.extensionName; + +import java.io.IOException; +import java.lang.reflect.ParameterizedType; import java.util.LinkedHashMap; import java.util.Map; import java.util.TreeMap; +import java.util.Map.Entry; import org.eclipse.microprofile.openapi.models.Extensible; +import org.eclipse.microprofile.openapi.models.Reference; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +@JsonSerialize(using = ExtensibleTreeMap.ExtensibleTreeMapSerializer.class) public abstract class ExtensibleTreeMap> extends TreeMap implements Extensible { @@ -29,20 +40,61 @@ public final Map getExtensions() { @Override public final void setExtensions(Map extensions) { - this.extensions = extensions; + this.extensions.clear(); + for (Entry entry : extensions.entrySet()) { + this.extensions.put(extensionName(entry.getKey()), entry.getValue()); + } } @SuppressWarnings("unchecked") @Override public final T addExtension(String name, Object value) { - if (value != null && name.startsWith("x-")) { - this.extensions.put(name, value); + if (value != null) { + this.extensions.put(extensionName(name), value); } return (T) this; } @Override public final void removeExtension(String name) { - this.extensions.remove(name); + this.extensions.remove(extensionName(name)); + } + + /** + * Custom {@link JsonSerializer} that adds both the extended {@link TreeMap} entries as well as the + * {@link ExtensibleTreeMap#extensions} map to the output object unless the value represents a {@link Reference} in + * which case only the {@link Reference#getRef()} is added. + */ + static class ExtensibleTreeMapSerializer extends JsonSerializer> { + + @Override + public void serialize(ExtensibleTreeMap value, JsonGenerator gen, SerializerProvider serializers) + throws IOException { + if (value instanceof Reference) { + Reference reference = (Reference) value; + String ref = reference.getRef(); + if (ref != null) { + gen.writeStartObject(value); + gen.writeFieldName("$ref"); + gen.writeString(ref); + gen.writeEndObject(); + return; // if this is a ref no extensions or map entries are relevant + } + } + gen.writeStartObject(value); + ParameterizedType mapType = (ParameterizedType) value.getClass().getGenericSuperclass(); + Class valueType = (Class) mapType.getActualTypeArguments()[0]; + JsonSerializer valueSerializer = serializers.findValueSerializer(valueType); + for (Map.Entry entry : value.entrySet()) { + gen.writeFieldName(entry.getKey()); + valueSerializer.serialize(entry.getValue(), gen, serializers); + } + for (Map.Entry extension : value.getExtensions().entrySet()) { + gen.writeFieldName(extension.getKey()); + Object extensionValue = extension.getValue(); + serializers.findValueSerializer(extensionValue.getClass()).serialize(extensionValue, gen, serializers); + } + gen.writeEndObject(); + } } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java index 99fd4de5066..e1ea4150c79 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponsesImpl.java @@ -41,7 +41,6 @@ import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.isAnnotationNull; -import java.util.HashMap; import java.util.Map; import org.eclipse.microprofile.openapi.models.media.Schema; @@ -55,8 +54,6 @@ public class APIResponsesImpl extends ExtensibleTreeMap extensions = new HashMap<>(); - public APIResponsesImpl() { super(); } From 9ecae7270b2b45b66d5fe68d43a735cfa5c908ff Mon Sep 17 00:00:00 2001 From: Andrew Pielage Date: Tue, 19 Mar 2019 10:11:24 +0000 Subject: [PATCH 045/108] Correct spelling and remove commented out code --- .../java/com/sun/enterprise/v3/admin/SetCommand.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java index 58e1a46410b..1d684c3d32d 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/SetCommand.java @@ -353,7 +353,7 @@ private void checkSharedConfigChange(AdminCommandContext context, TreeNode prima // if the user thinks server configuration is being changed, warn him if matching nodes are different Set sharedConfigs = findSharedConfigs(); // from matching nodes, find the roots that are in parentNodes - String targetedSharedConfigs = mNodes.stream() + String targettedSharedConfigs = mNodes.stream() .map(Map.Entry::getKey) .map(sourceNodes::get) // should definitely be in the map, but just to be sure @@ -364,10 +364,10 @@ private void checkSharedConfigChange(AdminCommandContext context, TreeNode prima .map(Dom::getKey) .collect(Collectors.joining(", ")); - if (!targetedSharedConfigs.isEmpty()) { + if (!targettedSharedConfigs.isEmpty()) { warning(context, localStrings.getLocalString("admin.set.sharedconfig", "Warning: command appears to address server {0}, but addresses following shared configuration(s): {1}", - primaryNode.name, targetedSharedConfigs)); + primaryNode.name, targettedSharedConfigs)); } } @@ -494,8 +494,6 @@ public Object run(Domain domain) throws PropertyVetoException, TransactionFailur },domain); return replicatePropertyChange(context, op, targetName); } catch (TransactionFailure transactionFailure) { - //fail(context, "Could not change the attributes: " + - // transactionFailure.getMessage(), transactionFailure); fail(context, localStrings.getLocalString("admin.set.attribute.change.failure", "Could not change the attributes: {0}", transactionFailure.getMessage()), transactionFailure); return false; @@ -510,7 +508,6 @@ private boolean setProperty(AdminCommandContext context, String pattern, SetOper pattern = parentNodes_[0].relativeName; Map matchingNodes_ = getMatchingNodes(dottedNames, pattern); if (matchingNodes_.isEmpty()) { - //fail(context, "No configuration found for " + targetName); fail(context, localStrings.getLocalString("admin.set.configuration.notfound", "No configuration found for {0}", targetName)); return false; } @@ -520,7 +517,6 @@ private boolean setProperty(AdminCommandContext context, String pattern, SetOper } } if (parentNode == null) { - //fail(context, "No configuration found for " + targetName); fail(context, localStrings.getLocalString("admin.set.configuration.notfound", "No configuration found for {0}", targetName)); return false; } @@ -545,8 +541,6 @@ private boolean setProperty(AdminCommandContext context, String pattern, SetOper ConfigSupport.createAndSet((ConfigBean) parentNode, Property.class, attributes); return replicatePropertyChange(context, op, targetName); } catch (TransactionFailure transactionFailure) { - //fail(context, "Could not change the attributes: " + - // transactionFailure.getMessage(), transactionFailure); fail(context, localStrings.getLocalString("admin.set.attribute.change.failure", "Could not change the attributes: {0}", transactionFailure.getMessage()), transactionFailure); return false; From 9689d401288c03e741bd464fad394d9b490a414f Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Tue, 19 Mar 2019 14:07:14 +0100 Subject: [PATCH 046/108] PAYARA-3419: Do not try to create timers on DAS when target is a deployment group Deployment Group does not refer to any specific configuration, therefore no timer service exists for the target. --- .../java/org/glassfish/ejb/startup/EjbDeployer.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/appserver/ejb/ejb-container/src/main/java/org/glassfish/ejb/startup/EjbDeployer.java b/appserver/ejb/ejb-container/src/main/java/org/glassfish/ejb/startup/EjbDeployer.java index 11ec2aea044..6a48b8c8af6 100644 --- a/appserver/ejb/ejb-container/src/main/java/org/glassfish/ejb/startup/EjbDeployer.java +++ b/appserver/ejb/ejb-container/src/main/java/org/glassfish/ejb/startup/EjbDeployer.java @@ -469,11 +469,15 @@ public void event(Event event) { } boolean createTimers = true; - if (!(opsparams.origin.isDeploy() || opsparams.origin.isCreateAppRef()) || env.getInstanceName().equals(dcp.target)) { - // Do real work only on deploy for a cluster or create-application-ref (the latter will + boolean isDeploymentGroup = domain.getDeploymentGroupNamed(dcp.target) != null; + boolean isDeployment = opsparams.origin.isDeploy() || opsparams.origin.isCreateAppRef(); + boolean isDirectTarget = env.getInstanceName().equals(dcp.target); + // Create timers on DAS only if this condition is not met + if (!isDeployment || isDirectTarget || isDeploymentGroup) { + // Create them on deploy for a cluster or create-application-ref (the latter will // check if it's the 1st ref being added or a subsequent one (timers with this unique id are present // or not) - // Timers will be created by the BaseContainer if it's a single instance deploy + // Otherwise, timers will be created by the BaseContainer if it's a single instance deploy if (_logger.isLoggable(Level.FINE)) { _logger.log(Level.FINE, "EjbDeployer ... will only set the timeout application flag if any"); } From 2e83617012afb0d208cb243a779a62b6a1dd86f0 Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Tue, 19 Mar 2019 15:50:29 +0100 Subject: [PATCH 047/108] PAYARA-3419: Support persistence type None for EJB Timer Service This will use non-persistent timer -- all timers run only on node where they were created and not persist across restarts. --- .../org/glassfish/ejb/config/EjbTimerService.java | 15 +++++++++++---- .../com/sun/ejb/containers/EJBTimerService.java | 8 ++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/appserver/ejb/ejb-connector/src/main/java/org/glassfish/ejb/config/EjbTimerService.java b/appserver/ejb/ejb-connector/src/main/java/org/glassfish/ejb/config/EjbTimerService.java index 40d2d9264b3..e513e7f2543 100644 --- a/appserver/ejb/ejb-connector/src/main/java/org/glassfish/ejb/config/EjbTimerService.java +++ b/appserver/ejb/ejb-connector/src/main/java/org/glassfish/ejb/config/EjbTimerService.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2016-2018] [Payara Foundation] +// Portions Copyright [2016-2019] [Payara Foundation] package org.glassfish.ejb.config; @@ -68,6 +68,8 @@ @Configured public interface EjbTimerService extends ConfigBeanProxy, PropertyBag { + static String TYPE_NONE = "None"; + static String TYPE_DATABASE = "Database"; /** * Gets the value of the minimumDeliveryIntervalInMillis property. @@ -160,11 +162,16 @@ public interface EjbTimerService extends ConfigBeanProxy, PropertyBag { * Gets the value of the EJB Timer Service property. * * The EJB Timer Service type to use in Payara. + * Supported values: + *
      + *
    • {@value #TYPE_DATABASE} for database-backed persistence
    • + *
    • "DataGrid" for DataGrid-backed persistence
    • + *
    • {@value #TYPE_NONE} for non-persistent timer service
    • + *
    * - * @return possible object is - * {@link String } + * @return One of the options above */ - @Attribute (defaultValue="Database") + @Attribute (defaultValue=TYPE_DATABASE) String getEjbTimerService(); /** diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EJBTimerService.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EJBTimerService.java index dd0c998b01f..99f9d8cf6ba 100755 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EJBTimerService.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EJBTimerService.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2016-2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] package com.sun.ejb.containers; import java.io.Serializable; @@ -391,9 +391,11 @@ private static synchronized void initNonPersistentTimerService(String target, bo private static synchronized void initPersistentTimerService(String target, boolean force) { if (persistentTimerService == null) { + EjbContainerUtil ejbContainerUtil = EjbContainerUtilImpl.getInstance(); + String serviceType = ejbContainerUtil.getEjbContainer().getEjbTimerService().getEjbTimerService(); List persistentTSList = EjbContainerUtilImpl.getInstance().getServices().getAllServices(PersistentTimerService.class); - if (persistentTSList.isEmpty()) { + if (persistentTSList.isEmpty() || EjbTimerService.TYPE_NONE.equals(serviceType)) { try { persistentTimerService = new NonPersistentEJBTimerService(); persistentTimerServiceVerified = true; @@ -403,8 +405,6 @@ private static synchronized void initPersistentTimerService(String target, boole } else { synchronized (LOCK) { // choose service based on the configuration setting - EjbContainerUtil ejbContainerUtil = EjbContainerUtilImpl.getInstance(); - String serviceType = ejbContainerUtil.getEjbContainer().getEjbTimerService().getEjbTimerService(); PersistentTimerService persistentTS = null; for (PersistentTimerService pts : persistentTSList) { if (pts.getClass().getSimpleName().startsWith(serviceType)) { From 2c839fe94fefc717b6b6658afb31aa8379606e2e Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Tue, 19 Mar 2019 16:22:51 +0100 Subject: [PATCH 048/108] PAYARA-3419: Admin UI for EJB Timer persistence type None --- .../main/resources/configuration/ejbContainerTimerService.jsf | 3 ++- .../resources/org/glassfish/ejb/admingui/Strings.properties | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/appserver/admingui/ejb/src/main/resources/configuration/ejbContainerTimerService.jsf b/appserver/admingui/ejb/src/main/resources/configuration/ejbContainerTimerService.jsf index 8c0671ba9fa..0e7497e41ba 100644 --- a/appserver/admingui/ejb/src/main/resources/configuration/ejbContainerTimerService.jsf +++ b/appserver/admingui/ejb/src/main/resources/configuration/ejbContainerTimerService.jsf @@ -39,6 +39,7 @@ holder. --> + @@ -98,7 +99,7 @@ - + diff --git a/appserver/admingui/ejb/src/main/resources/org/glassfish/ejb/admingui/Strings.properties b/appserver/admingui/ejb/src/main/resources/org/glassfish/ejb/admingui/Strings.properties index be7340c1843..838638e3cdf 100644 --- a/appserver/admingui/ejb/src/main/resources/org/glassfish/ejb/admingui/Strings.properties +++ b/appserver/admingui/ejb/src/main/resources/org/glassfish/ejb/admingui/Strings.properties @@ -37,6 +37,7 @@ # only if the new code is made subject to such option by the copyright # holder. # +# Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] ejb.NumBeans=Number of beans @@ -65,7 +66,7 @@ ejbTimerSettings.redeliveryIntrHelp=Time between redelivery attempts ejbTimerSettings.timerDatasourceLabel=Timer Datasource: ejbTimerSettings.timerDatasourceLabelHelp=JNDI name of the JDBC resource that will be used as the timer datasource when Database is selected as the Persistence Service ejbTimerSettings.persistenceServiceLabel=Persistence Service -ejbTimerSettings.persistenceServiceHelp=Persistence Service for storing Persistent EJB Timers. Database stores in the specified datasource, DataGrid stores timers in-memory in the Data Grid. In Data Grid mode if all Data Grid instances are shutdown persistent timers will be lost +ejbTimerSettings.persistenceServiceHelp=Persistence Service for storing Persistent EJB Timers. Database stores in the specified datasource, DataGrid stores timers in-memory in the Data Grid. In Data Grid mode if all Data Grid instances are shutdown persistent timers will be lost. When mode is None, all timers are non-persistent. ejbTimerSettings.clusterFiringModeLabel=Clustered Timer Firing Mode ejbTimerSettings.clusterFiringModeHelp=Determines how clustered timers fire. One Per Data Grid - only one timer will be active in the data grid. One Per Deployment Group - only one timer will be active within the targeted deployment group. All Instances - Timer will be active on all instances where the application is deployed. From 13bd76c50fc0d3e901124f5a83dc8c20a28e24f0 Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Tue, 19 Mar 2019 16:58:51 +0100 Subject: [PATCH 049/108] PAYARA-3419: Remove unimplemented cluster-firing-mode from the UI Remains in config for compatibility reasons --- .../resources/configuration/ejbContainerTimerService.jsf | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/appserver/admingui/ejb/src/main/resources/configuration/ejbContainerTimerService.jsf b/appserver/admingui/ejb/src/main/resources/configuration/ejbContainerTimerService.jsf index 0e7497e41ba..a7d30343105 100644 --- a/appserver/admingui/ejb/src/main/resources/configuration/ejbContainerTimerService.jsf +++ b/appserver/admingui/ejb/src/main/resources/configuration/ejbContainerTimerService.jsf @@ -101,11 +101,7 @@ - - - - - + From 6be803bb9410689d0b72375c38769174bcee438b Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 19 Mar 2019 18:09:12 +0100 Subject: [PATCH 050/108] PAYARA-3466 fixed annotation processing (empty annotation detection), added test for callbacks, added components references to validator model --- .../impl/model/callbacks/CallbackImpl.java | 7 +- .../openapi/impl/model/util/ModelUtils.java | 7 +- .../impl/processor/ApplicationProcessor.java | 14 ++-- .../impl/model/ModelSerialisationTest.java | 58 -------------- .../openapi/impl/model/ModelTestUtil.java | 33 -------- .../microprofile/openapi/spec/NodeType.java | 18 ++--- .../openapi/spec/OpenAPIValidator.java | 6 +- .../test/app/OpenAPIApplicationTest.java | 54 ++++++++++++- .../test/app/application/CallbacksTest.java | 75 +++++++++++++++++++ .../test/app/application/ResponseTest.java | 2 +- .../test/app/application/RootPathTest.java | 4 +- .../openapi/test/app/data/TestComponent.java | 2 +- 12 files changed, 156 insertions(+), 124 deletions(-) delete mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java delete mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelTestUtil.java create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java index dad382c3898..3d7f5866f0c 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java @@ -117,9 +117,10 @@ public static void merge(org.eclipse.microprofile.openapi.annotations.callbacks. applyReference(to, from.ref()); return; } - if (!from.callbackUrlExpression().isEmpty()) { - PathItem pathItem = to.getOrDefault(from.callbackUrlExpression(), new PathItemImpl()); - to.addPathItem(from.callbackUrlExpression(), pathItem); + String urlExpression = from.callbackUrlExpression(); + if (!urlExpression.isEmpty()) { + PathItem pathItem = to.getOrDefault(urlExpression, new PathItemImpl()); + to.addPathItem(urlExpression, pathItem); if (from.operations() != null) { for (CallbackOperation callbackOperation : from.operations()) { applyCallbackOperationAnnotation(pathItem, callbackOperation, override, currentSchemas); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java index a0202bc73df..c20794d73bb 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java @@ -395,7 +395,6 @@ public static boolean isAnnotationNull(Annotation annotation) { if (annotation == null) { return true; } - boolean allNull = true; for (Method m : annotation.annotationType().getDeclaredMethods()) { if (m.getParameterCount() == 0) { try { @@ -416,7 +415,9 @@ public static boolean isAnnotationNull(Annotation annotation) { } else if (String.class.isAssignableFrom(value.getClass()) && !value.toString().isEmpty()) { return false; } else if (value instanceof Annotation) { - allNull = isAnnotationNull((Annotation) value); + if (!isAnnotationNull((Annotation) value)) { + return false; + } } } } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { @@ -424,7 +425,7 @@ public static boolean isAnnotationNull(Annotation annotation) { } } } - return allNull; + return true; } public static Boolean mergeProperty(Boolean current, boolean offer, boolean override) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java index 7d81b251f8c..de2659d0d86 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java @@ -74,6 +74,7 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.Application; +import org.eclipse.microprofile.openapi.annotations.Components; import org.eclipse.microprofile.openapi.annotations.ExternalDocumentation; import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition; import org.eclipse.microprofile.openapi.annotations.Operation; @@ -108,6 +109,7 @@ import fish.payara.microprofile.openapi.api.visitor.ApiVisitor; import fish.payara.microprofile.openapi.api.visitor.ApiWalker; import fish.payara.microprofile.openapi.impl.config.OpenApiConfiguration; +import fish.payara.microprofile.openapi.impl.model.ComponentsImpl; import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; import fish.payara.microprofile.openapi.impl.model.ExternalDocumentationImpl; import fish.payara.microprofile.openapi.impl.model.OpenAPIImpl; @@ -686,14 +688,10 @@ public void visitCallbacks(Callbacks callbacks, AnnotatedElement element, ApiCon @Override public void visitRequestBody(RequestBody requestBody, AnnotatedElement element, ApiContext context) { if (element instanceof Method) { - if (context.getWorkingOperation().getRequestBody() != null) { - RequestBodyImpl.merge(requestBody, context.getWorkingOperation().getRequestBody(), true, - context.getApi().getComponents().getSchemas()); - } - } - if (element instanceof java.lang.reflect.Parameter) { - if (context.getWorkingOperation().getRequestBody() != null) { - RequestBodyImpl.merge(requestBody, context.getWorkingOperation().getRequestBody(), true, + org.eclipse.microprofile.openapi.models.parameters.RequestBody currentRequestBody = context + .getWorkingOperation().getRequestBody(); + if (currentRequestBody != null || element instanceof java.lang.reflect.Parameter) { + RequestBodyImpl.merge(requestBody, currentRequestBody, true, context.getApi().getComponents().getSchemas()); } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java deleted file mode 100644 index 525bbfd60c3..00000000000 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelSerialisationTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package fish.payara.microprofile.openapi.impl.model; - -import static fish.payara.microprofile.openapi.impl.model.ModelTestUtil.newCallback; -import static fish.payara.microprofile.openapi.impl.model.ModelTestUtil.newCallbackRef; -import static fish.payara.microprofile.openapi.impl.model.ModelTestUtil.newPathItemRef; -import static org.junit.Assert.assertNotNull; - -import org.eclipse.microprofile.openapi.models.Constructible; -import org.eclipse.microprofile.openapi.models.examples.Example; -import org.junit.Test; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import fish.payara.microprofile.openapi.impl.model.examples.ExampleImpl; -import fish.payara.microprofile.openapi.impl.rest.app.provider.ObjectMapperFactory; -import fish.payara.microprofile.openapi.spec.NodeType; -import fish.payara.microprofile.openapi.spec.OpenAPIValidator; - -/** - * A test that should help detect (and thereby avoid) changes in the model that do serialise to an non valid Open API - * document. This can happen quite easily since we use "automatic" serialisation with jackson that picks up getters - * (unless explicitly told not to). This might not seem a big thing at first but adding anything to the document that - * isn't expected or allowed makes the resulting Open API document invalid. Therefore this test creates model objects, - * serialises them to JSON and validates the tree against the Open API specification as modeled by {@link NodeType}. - */ -public class ModelSerialisationTest { - - private static final ObjectMapper JSON_MAPPER = ObjectMapperFactory.createJson(); - - @Test - public void callbackWithRef() { - assertValid(NodeType.Reference, newCallbackRef("#/components/schemas/SomePayload")); - } - - @Test - public void callbackWithPathItem() { - assertValid(NodeType.Callback, newCallback("foo", newPathItemRef("#bar"))); - } - - @Test - public void callbackWithExtension() { - assertValid(NodeType.Callback, newCallback("foo", newPathItemRef("#bar")) - .addExtension("hello", "world")); - } - - @Test - public void exampleWithExtension() { - Example ex = new ExampleImpl(); - ex = ex.addExtension("x-hello", "world"); - assertValid(NodeType.Example, ex); - } - - private static void assertValid(NodeType type, Constructible node) { - assertNotNull("The example tested should not be null", node); - OpenAPIValidator.validate(type, JSON_MAPPER.valueToTree(node)); - } - -} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelTestUtil.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelTestUtil.java deleted file mode 100644 index c41e12aa146..00000000000 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelTestUtil.java +++ /dev/null @@ -1,33 +0,0 @@ -package fish.payara.microprofile.openapi.impl.model; - -import java.util.Collections; -import java.util.function.Supplier; - -import org.eclipse.microprofile.openapi.models.PathItem; -import org.eclipse.microprofile.openapi.models.Reference; -import org.eclipse.microprofile.openapi.models.callbacks.Callback; - -import fish.payara.microprofile.openapi.impl.model.callbacks.CallbackImpl; - -public class ModelTestUtil { - - static Callback newCallbackRef(String ref) { - return newRef(ref, CallbackImpl::new); - } - - static Callback newCallback(String expression, PathItem item) { - Callback callback = new CallbackImpl(); - callback.setPathItems(Collections.singletonMap(expression, item)); - return callback; - } - - static PathItem newPathItemRef(String ref) { - return newRef(ref, PathItemImpl::new); - } - - private static > T newRef(String ref, Supplier constructor) { - T reference = constructor.get(); - reference.setRef(ref); - return reference; - } -} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java index e3e55c5853d..c49e060497a 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java @@ -148,15 +148,15 @@ NodeType extensible() { .extensible(); Components - .addField("schemas", Schema).map() - .addField("responses", Response).map() - .addField("parameters", Parameter).map() - .addField("examples", Example).map() - .addField("requestBodies", RequestBody).map() - .addField("headers", Header).map() - .addField("securitySchemes", SecurityScheme).map() - .addField("links", Link).map() - .addField("callbacks", Callback).map() + .addField("schemas", Schema, Reference).map() + .addField("responses", Response, Reference).map() + .addField("parameters", Parameter, Reference).map() + .addField("examples", Example, Reference).map() + .addField("requestBodies", RequestBody, Reference).map() + .addField("headers", Header, Reference).map() + .addField("securitySchemes", SecurityScheme, Reference).map() + .addField("links", Link, Reference).map() + .addField("callbacks", Callback, Reference).map() .extensible(); Paths diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java index e9445a6ad7a..49ef4c763a0 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java @@ -138,14 +138,12 @@ private static void assertJsonType(JsonNodeType expectedJsonType, Iterable Date: Tue, 19 Mar 2019 17:37:27 +0000 Subject: [PATCH 051/108] Add details about reproducible test case to CONTRIBUTING.md --- .github/CONTRIBUTING.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index cc60b847e34..0bfba451a55 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -160,11 +160,14 @@ If you feel there is a security vulnerability in Payara Server or Payara Micro p If you find a bug within Payara, please post it as a github issue. Github is our main repository for community found issues with Payara and our support team frequently monitor it for new issues. As with submitting issues, a concise title which clearly explains the issue combined with a comment explaining what the found issue is and either how it arose and a stacktrace of the issue, or a test case which is able to reproduce the issue will help us deliver a patch. +### Executable Test Case +For a bug report to be actioned quickly an executable test case is required. Ideally the test case will be hosted in your GitHub account as a buildable maven project which creates a deployable artifact that demonstrates the issue clearly. I'm afraid we can't get into the details of debugging your specific business application so the test case should be stripped to the minimum required to demonstrate the issue. If additional server resources need creating e.g. Connection Pools or Queues please provide the asadmin commands required to create these in a document or as a script. The reality is the easier it is for an engineer to quickly reproduce your issue the more likely it will be fixed. + ## Responses We continually check the github posted issues for bugs, feature requests, and assorted issues. If you have posted an issue, chances are it has been read by a member of staff. Requests for further information and labels are often posted in order to make it easier for the dev team to see issues. However if your issue has not received a comment or label, don't take this as it having not been read or acted upon! -If you do post an issue and we request further information from you please respond quickly. We review all issues periodically and if an issue has been waiting for a response since last review we will add the "requestor unresponsive" label. If on the second periodic review there has still been no response to our request we will add a second "requestor unresponsive" label. Finally if on the third review there is still no response we will close the issue. This ensures our GitHub issues stay up to date and relevant and don't get full of old issues. If you still have the same problem you can still comment on the closed issue and we will still see it and if necessary reopen the issue to pick up where we left off. +If you do post an issue and we request further information from you please respond quickly. We review all issues periodically and if an issue has been waiting for a response since last review we will add the "requestor unresponsive" label. If on the second periodic review there has still been no response to our request we will add a second "requestor unresponsive" label. Finally if on the third review there is still no response we will close the issue. This ensures our GitHub issues stay up to date and relevant and doesn't get full of old issues. If you still have the same problem you can still comment on the closed issue and we will still see it and if necessary reopen the issue to pick up where we left off. ## Questions, advice and guidance From 54613c5eb2629d3b72e1bef0017135a61fb5d0c8 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Wed, 20 Mar 2019 13:33:32 +0100 Subject: [PATCH 052/108] PAYARA-3466 tested and fixed GH #3724 (filters), changed names to conform to guideline --- .../openapi/impl/model/media/SchemaImpl.java | 6 +++ .../impl/processor/FilterProcessor.java | 10 +++- .../impl/model/OpenApiBuilderTest.java | 34 ++++++++++++ .../openapi/impl/model/SchemaBuilderTest.java | 43 +++++++++++++++ .../rule/ApplicationProcessedDocument.java | 14 +++-- .../microprofile/openapi/spec/Field.java | 10 ---- ...PIValidator.java => OpenApiValidator.java} | 18 ++++--- ...torTest.java => OpenApiValidatorTest.java} | 10 ++-- .../test/app/OpenApiApplicationTest.java | 52 +++++++++++++++++++ .../test/app/application/CallbacksTest.java | 6 ++- .../test/app/application/OASFilterTest.java | 51 ++++++++++++++++++ .../test/app/application/ResponseTest.java | 4 +- .../test/app/application/RootPathTest.java | 4 +- .../openapi/test/app/data/TestComponent.java | 4 +- .../JsonUtils.java} | 50 +++++------------- 15 files changed, 244 insertions(+), 72 deletions(-) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OpenApiBuilderTest.java create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SchemaBuilderTest.java rename appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/{OpenAPIValidator.java => OpenApiValidator.java} (91%) rename appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/{OpenAPIValidatorTest.java => OpenApiValidatorTest.java} (74%) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenApiApplicationTest.java create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/OASFilterTest.java rename appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/{app/OpenAPIApplicationTest.java => util/JsonUtils.java} (52%) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java index 9f2f20aba81..b44c8e91c86 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java @@ -58,6 +58,9 @@ import org.eclipse.microprofile.openapi.models.media.Schema; import org.eclipse.microprofile.openapi.models.media.XML; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; import fish.payara.microprofile.openapi.impl.model.ExternalDocumentationImpl; import fish.payara.microprofile.openapi.impl.model.util.ModelUtils; @@ -354,6 +357,7 @@ public void removeProperty(String key) { this.properties.remove(key); } + @JsonProperty("additionalProperties") @Override public Object getAdditionalProperties() { return additionalProperties; @@ -364,11 +368,13 @@ public void setAdditionalProperties(Schema additionalProperties) { this.additionalProperties = additionalProperties; } + @JsonIgnore @Override public Schema getAdditionalPropertiesSchema() { return additionalProperties instanceof Schema ? (Schema) additionalProperties : null; } + @JsonIgnore @Override public Boolean getAdditionalPropertiesBoolean() { return additionalProperties instanceof Boolean ? (Boolean)additionalProperties : null; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java index 50cc7a506eb..b115f5d280c 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java @@ -80,10 +80,18 @@ public class FilterProcessor implements OASProcessor { */ private OASFilter filter; + public FilterProcessor() { + this(null); + } + + public FilterProcessor(OASFilter filter) { + this.filter = filter; + } + @Override public OpenAPI process(OpenAPI api, OpenApiConfiguration config) { try { - if (config.getFilter() != null) { + if (filter == null && config.getFilter() != null) { filter = config.getFilter().newInstance(); } } catch (InstantiationException | IllegalAccessException ex) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OpenApiBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OpenApiBuilderTest.java new file mode 100644 index 00000000000..9f2fae94a32 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OpenApiBuilderTest.java @@ -0,0 +1,34 @@ +package fish.payara.microprofile.openapi.impl.model; + +import org.eclipse.microprofile.openapi.OASFactory; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.info.Info; +import org.junit.Before; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import fish.payara.microprofile.openapi.impl.rest.app.provider.ObjectMapperFactory; + +public abstract class OpenApiBuilderTest { + + public static final ObjectMapper JSON_MAPPER = ObjectMapperFactory.createJson(); + + protected abstract void setupBaseDocument(OpenAPI document); + + private OpenAPI document; + + @Before + public void setupDocument() { + document = OASFactory.createObject(OpenAPI.class); + Info info = OASFactory.createObject(Info.class); + info.setTitle("additionalProperties-render"); + info.setVersion("1.0"); + document.setInfo(info); + document.setOpenapi("3.0.0"); + setupBaseDocument(document); + } + + public OpenAPI getDocument() { + return document; + } +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SchemaBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SchemaBuilderTest.java new file mode 100644 index 00000000000..77c51f5852d --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SchemaBuilderTest.java @@ -0,0 +1,43 @@ +package fish.payara.microprofile.openapi.impl.model; + +import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; +import static fish.payara.microprofile.openapi.test.util.JsonUtils.toJson; +import static org.eclipse.microprofile.openapi.OASFactory.createObject; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.media.Schema; +import org.eclipse.microprofile.openapi.models.media.Schema.SchemaType; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import fish.payara.microprofile.openapi.spec.OpenApiValidator; + +public class SchemaBuilderTest extends OpenApiBuilderTest { + + @Override + protected void setupBaseDocument(OpenAPI document) { + document.getComponents().getSchemas().put("SimpleMap", createObject(Schema.class) + .type(SchemaType.OBJECT) + .additionalPropertiesSchema(createObject(Schema.class).type(SchemaType.STRING))); + } + + @Test + public void isValidJsonDocument() { + OpenApiValidator.validate(toJson(getDocument())); + } + + @Test + public void schemaAdditionalPropertiesStructure() { + ObjectNode openAPI = toJson(getDocument()); + JsonNode mapEntry = path(openAPI, "components.schemas.SimpleMap"); + assertNotNull(mapEntry); + assertEquals("object", mapEntry.get("type").textValue()); + JsonNode additionalProperties = mapEntry.get("additionalProperties"); + assertNotNull(additionalProperties); + assertEquals("string", additionalProperties.get("type").textValue()); + } +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java index 315b8a71a74..352b69a8cd8 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java @@ -42,11 +42,13 @@ import fish.payara.microprofile.openapi.impl.model.OpenAPIImpl; import fish.payara.microprofile.openapi.impl.processor.ApplicationProcessor; import fish.payara.microprofile.openapi.impl.processor.BaseProcessor; +import fish.payara.microprofile.openapi.impl.processor.FilterProcessor; import fish.payara.microprofile.openapi.resource.classloader.ApplicationClassLoader; import fish.payara.microprofile.openapi.test.app.TestApplication; import java.net.URL; import java.util.HashSet; +import org.eclipse.microprofile.openapi.OASFilter; import org.eclipse.microprofile.openapi.models.OpenAPI; import static java.util.Arrays.asList; @@ -55,16 +57,22 @@ public class ApplicationProcessedDocument { public static OpenAPI createDocument(Class... extraClasses) { + return createDocument(null, extraClasses); + } + + public static OpenAPI createDocument(Class filter, Class... extraClasses) { try { + ApplicationClassLoader appClassLoader = new ApplicationClassLoader(new TestApplication(), + new HashSet<>(asList(extraClasses))); OpenAPIImpl document = new OpenAPIImpl(); // Apply base processor new BaseProcessor(asList(new URL("http://localhost:8080/testlocation_123"))).process(document, null); - ApplicationClassLoader appClassLoader = new ApplicationClassLoader(new TestApplication(), - new HashSet<>(asList(extraClasses))); - // Apply application processor new ApplicationProcessor(appClassLoader.getApplicationClasses()).process(document, null); + if (filter != null) { + new FilterProcessor(filter.newInstance()).process(document, null); + } return document; } catch (Exception ex) { ex.printStackTrace(); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java index c9e8ff0e2b2..2c54768c32d 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java @@ -5,8 +5,6 @@ public final class Field implements Iterable { - private static final NodeType[] ALL_NODE_TYPES = NodeType.values(); - final String name; final EnumSet oneOfTypes = EnumSet.noneOf(NodeType.class); boolean isRequired = false; @@ -33,18 +31,10 @@ public boolean isArray() { return isArray; } - public boolean isOneOfManyTypes() { - return oneOfTypes.size() > 0; - } - public boolean isAnyType() { return oneOfTypes.isEmpty(); } - public NodeType type() { - return oneOfTypes.iterator().next(); - } - @Override public Iterator iterator() { return oneOfTypes.iterator(); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenApiValidator.java similarity index 91% rename from appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java rename to appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenApiValidator.java index 49ef4c763a0..fe7813699b3 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenAPIValidator.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenApiValidator.java @@ -13,12 +13,20 @@ import java.util.stream.Collectors; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeType; import com.fasterxml.jackson.databind.node.ObjectNode; -public class OpenAPIValidator { +import fish.payara.microprofile.openapi.test.util.JsonUtils; + +/** + * Uses the structural model described by {@link NodeType} to check a {@link JsonNode} document against the expected + * structure of a particular {@link NodeType}. + * + * This check is rough as most fields are optional (or optional under certain conditions which is just treated as fully + * optional) but this does detect malformed structures and illegal fields being used. + */ +public class OpenApiValidator { private static final EnumMap> REQUIRED_FIELDS = new EnumMap<>(NodeType.class); @@ -137,11 +145,7 @@ private static void assertJsonType(JsonNodeType expectedJsonType, Iterable filter = filterClass(); + document = filter == null + ? ApplicationProcessedDocument.createDocument(getClass()) + : ApplicationProcessedDocument.createDocument(filterClass(), getClass(), filterClass()); + jsonDocument = toJson(document); + } + + protected Class filterClass() { + return null; // override to customise + } + + public OpenAPI getDocument() { + return document; + } + + public ObjectNode getOpenAPIJson() { + return jsonDocument; + } + + @Test + public void documentIsValid() { + assertNotNull(document); + OpenApiValidator.validate(jsonDocument); + } + +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java index 5f399646db2..ee75bcf0818 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java @@ -1,5 +1,6 @@ package fish.payara.microprofile.openapi.test.app.application; +import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -21,7 +22,8 @@ import com.fasterxml.jackson.databind.JsonNode; -import fish.payara.microprofile.openapi.test.app.OpenAPIApplicationTest; +import fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest; +import fish.payara.microprofile.openapi.test.util.JsonUtils; @OpenAPIDefinition( info = @Info(title = "title", version = "version"), @@ -47,7 +49,7 @@ )) @Path("/callbacks") @Produces(MediaType.APPLICATION_JSON) -public class CallbacksTest extends OpenAPIApplicationTest { +public class CallbacksTest extends OpenApiApplicationTest { @Test public void callbackReference() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/OASFilterTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/OASFilterTest.java new file mode 100644 index 00000000000..a06d5c51ed7 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/OASFilterTest.java @@ -0,0 +1,51 @@ +package fish.payara.microprofile.openapi.test.app.application; + +import static org.eclipse.microprofile.openapi.OASFactory.createObject; +import static org.junit.Assert.assertEquals; + +import org.eclipse.microprofile.openapi.OASFilter; +import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition; +import org.eclipse.microprofile.openapi.annotations.info.Info; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.media.Schema; +import org.eclipse.microprofile.openapi.models.media.Schema.SchemaType; +import org.junit.Test; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +import fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest; +import fish.payara.microprofile.openapi.test.util.JsonUtils; + +/** + * In response to {@link https://github.com/payara/Payara/issues/3724} this tests checks that using a {@link OASFilter} + * to add a {@link Schema} with additional properties is successful. + */ +@OpenAPIDefinition( + info = @Info(title = "title", version = "version")) +public class OASFilterTest extends OpenApiApplicationTest { + + @Override + protected Class filterClass() { + return AdditionalPropertiesOASFilter.class; + } + + public static class AdditionalPropertiesOASFilter implements OASFilter { + + @Override + public void filterOpenAPI(final OpenAPI openAPI) { + openAPI.getComponents().getSchemas().put("SimpleMap", createMapKey()); + } + + private static Schema createMapKey() { + return createObject(Schema.class) + .type(SchemaType.OBJECT) + .additionalPropertiesSchema(createObject(Schema.class).type(SchemaType.STRING)); + } + } + + @Test + public void additionalPropertiesAreAddedByFilter() { + ObjectNode openAPI = getOpenAPIJson(); + assertEquals("string", JsonUtils.path(openAPI, "components.schemas.SimpleMap.additionalProperties.type").textValue()); + } +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java index d3c37c041e5..c5f149c53e4 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ResponseTest.java @@ -55,14 +55,14 @@ import org.eclipse.microprofile.openapi.models.responses.APIResponses; import org.junit.Test; -import fish.payara.microprofile.openapi.test.app.OpenAPIApplicationTest; +import fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest; /** * A resource to test that various response types are mapped properly. */ @Path("/response") @Produces({ APPLICATION_JSON, APPLICATION_XML }) -public class ResponseTest extends OpenAPIApplicationTest { +public class ResponseTest extends OpenApiApplicationTest { @GET @APIResponse(responseCode = "200", description = "success", diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java index 971551eda78..c4eb8cc04b2 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java @@ -47,13 +47,13 @@ import org.junit.Test; -import fish.payara.microprofile.openapi.test.app.OpenAPIApplicationTest; +import fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest; /** * A resource to test that a resource at the context root is mapped correctly. */ @Path("") -public class RootPathTest extends OpenAPIApplicationTest { +public class RootPathTest extends OpenApiApplicationTest { @GET public String getRoot() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java index 46237ccb156..171aecbd1d4 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java @@ -44,12 +44,12 @@ import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.junit.Test; -import fish.payara.microprofile.openapi.test.app.OpenAPIApplicationTest; +import fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest; /** * A test to check that schema objects without a @Schema annotation at the top are created. */ -public class TestComponent extends OpenAPIApplicationTest { +public class TestComponent extends OpenApiApplicationTest { @Schema(description = "Test property") private int property; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenAPIApplicationTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/util/JsonUtils.java similarity index 52% rename from appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenAPIApplicationTest.java rename to appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/util/JsonUtils.java index ade3b7ebb1a..2072e29825f 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenAPIApplicationTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/util/JsonUtils.java @@ -1,55 +1,25 @@ -package fish.payara.microprofile.openapi.test.app; +package fish.payara.microprofile.openapi.test.util; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.util.Arrays; -import org.eclipse.microprofile.openapi.models.OpenAPI; -import org.junit.Before; -import org.junit.Test; +import org.eclipse.microprofile.openapi.models.Constructible; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import fish.payara.microprofile.openapi.impl.rest.app.provider.ObjectMapperFactory; -import fish.payara.microprofile.openapi.resource.rule.ApplicationProcessedDocument; -import fish.payara.microprofile.openapi.spec.OpenAPIValidator; +import fish.payara.microprofile.openapi.impl.model.OpenApiBuilderTest; -public abstract class OpenAPIApplicationTest { +public class JsonUtils { - private static final ObjectMapper JSON_MAPPER = ObjectMapperFactory.createJson(); - - private OpenAPI document; - private ObjectNode jsonDocument; - - @Before - public void createDocument() { - document = ApplicationProcessedDocument.createDocument(getClass()); - jsonDocument = JSON_MAPPER.valueToTree(document); - } - - public OpenAPI getDocument() { - return document; - } - - public ObjectNode getOpenAPIJson() { - return jsonDocument; - } - - @Test - public void documentIsValid() { - assertNotNull(document); - OpenAPIValidator.validate(jsonDocument); - } - - protected static JsonNode path(JsonNode root, String path) { + public static JsonNode path(JsonNode root, String path) { return path(root, path.split("\\.")); } - protected static JsonNode path(JsonNode root, String... pathElements) { + public static JsonNode path(JsonNode root, String... pathElements) { JsonNode current = root; for (int i = 0; i < pathElements.length; i++) { String nameOrIndex = pathElements[i]; @@ -71,11 +41,15 @@ protected static JsonNode path(JsonNode root, String... pathElements) { return current; } - protected static String prettyPrint(JsonNode node) { + public static String prettyPrint(JsonNode node) { try { return new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(node); } catch (JsonProcessingException e) { - return node.toString(); // best we can do + return String.valueOf(node); // best we can do } } + + public static ObjectNode toJson(Constructible node) { + return OpenApiBuilderTest.JSON_MAPPER.valueToTree(node); + } } From f6d49215fdeff41bdc243937e46094743d1ffed4 Mon Sep 17 00:00:00 2001 From: Cuba Stanley Date: Wed, 20 Mar 2019 14:12:32 +0000 Subject: [PATCH 053/108] Fixed missing pom refactor --- appserver/packager/glassfish-ejb/pom.xml | 4 ++-- nucleus/admin/template/pom.xml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/appserver/packager/glassfish-ejb/pom.xml b/appserver/packager/glassfish-ejb/pom.xml index 88252769f9b..e0394a01564 100644 --- a/appserver/packager/glassfish-ejb/pom.xml +++ b/appserver/packager/glassfish-ejb/pom.xml @@ -100,8 +100,8 @@ ${project.version} - fish.payara.ejb.rest - ejb-rest-admin + fish.payara.ejb.http + ejb-http-admin ${project.version} diff --git a/nucleus/admin/template/pom.xml b/nucleus/admin/template/pom.xml index e662db4e9d9..7a7b5017ad5 100644 --- a/nucleus/admin/template/pom.xml +++ b/nucleus/admin/template/pom.xml @@ -60,8 +60,8 @@ - fish.payara.ejb.rest - ejb-rest-endpoint + fish.payara.ejb.http + ejb-http-endpoint ${project.version} war @@ -99,8 +99,8 @@ - fish.payara.ejb.rest - ejb-rest-endpoint + fish.payara.ejb.http + ejb-http-endpoint ${project.version} war false From cc8099fed310f0286b01c77dd03e936c5a26cbb2 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Wed, 20 Mar 2019 18:28:46 +0100 Subject: [PATCH 054/108] PAYARA-3466 actually useful toString for model --- .../openapi/impl/model/ExtensibleImpl.java | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index dd7207ee4de..b6398396b93 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -44,6 +44,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; @@ -147,20 +148,15 @@ public String toString() { } void toString(StringBuilder str, String indent) { - str.append(getClass().getSimpleName()); + str.append('[').append(getClass().getSimpleName()).append("] {"); Class type = getClass(); while (type != Object.class) { for (Field field : type.getDeclaredFields()) { if (!Modifier.isStatic(field.getModifiers()) && !field.isSynthetic()) { - str.append("\n").append(indent).append(field.getName()).append(": "); try { field.setAccessible(true); Object value = field.get(this); - if (value instanceof ExtensibleImpl) { - ((ExtensibleImpl)value).toString(str, indent + "\t"); - } else { - str.append(value); - } + toString(str, indent, field.getName(), value); } catch (IllegalArgumentException | IllegalAccessException e) { str.append(""); } @@ -168,5 +164,41 @@ void toString(StringBuilder str, String indent) { } type = type.getSuperclass(); } + str.append('\n').append(indent.length() > 0 ? indent.substring(1) : indent).append('}'); + } + + private static void toString(StringBuilder str, String indent, Object key, Object value) { + if (isNonEmpty(value)) { + str.append("\n").append(indent).append('"').append(key).append('"').append(": "); + if (value instanceof ExtensibleImpl) { + ((ExtensibleImpl)value).toString(str, indent + "\t"); + } else if (value instanceof Map) { + str.append('{'); + for (Entry entry : ((Map) value).entrySet()) { + toString(str, indent + '\t', entry.getKey(), entry.getValue()); + } + str.append('\n').append(indent).append('}'); + } else if (value instanceof String) { + str.append('"').append(value).append('"'); + } else { + str.append(value); + } + } + } + + private static boolean isNonEmpty(Object value) { + if (value == null) { + return false; + } + if (value instanceof Object[]) { + return ((Object[])value).length > 0; + } + if (value instanceof Collection) { + return ((Collection) value).size() > 0; + } + if (value instanceof Map) { + return ((Map) value).size() > 0; + } + return true; } } \ No newline at end of file From e8960c3ddc4fba93e5b7380e197ead2b9d20bcb2 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Wed, 20 Mar 2019 18:29:26 +0100 Subject: [PATCH 055/108] PAYARA-3466 Schema reference test for GH #3832 --- .../impl/processor/ApplicationProcessor.java | 31 +++++---- .../test/app/application/ReferenceTest.java | 63 +++++++++++++++++++ 2 files changed, 82 insertions(+), 12 deletions(-) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ReferenceTest.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java index de2659d0d86..dfc0b132c6f 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java @@ -132,6 +132,8 @@ import fish.payara.microprofile.openapi.impl.visitor.OpenApiWalker; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + import org.eclipse.microprofile.openapi.models.parameters.Parameter.Style; /** @@ -547,7 +549,7 @@ private void visitSchemaClass(Schema schema, Class clazz, ApiContext context) Map fields = new LinkedHashMap<>(); for (Field field : clazz.getDeclaredFields()) { if (!Modifier.isTransient(field.getModifiers())) { - fields.put(field.getName(), createSchema(context, clazz, field.getType())); + fields.put(field.getName(), createSchema(context, clazz, field.getType(), field.getGenericType())); } } newSchema.setProperties(fields); @@ -951,9 +953,11 @@ private org.eclipse.microprofile.openapi.models.parameters.RequestBody insertDef // Get the request body type of the method Class bodyType = null; + Type genericBodyType = null; for (java.lang.reflect.Parameter methodParam : method.getParameters()) { if (ModelUtils.isRequestBody(methodParam)) { bodyType = methodParam.getType(); + genericBodyType = methodParam.getParameterizedType(); break; } } @@ -962,7 +966,7 @@ private org.eclipse.microprofile.openapi.models.parameters.RequestBody insertDef } // Create the default request body with a wildcard mediatype - MediaType mediaType = new MediaTypeImpl().schema(createSchema(context, bodyType)); + MediaType mediaType = new MediaTypeImpl().schema(createSchema(context, bodyType, genericBodyType)); requestBody.getContent().addMediaType(javax.ws.rs.core.MediaType.WILDCARD, mediaType); operation.setRequestBody(requestBody); @@ -984,7 +988,7 @@ private org.eclipse.microprofile.openapi.models.responses.APIResponse insertDefa defaultResponse.setDescription("Default Response."); // Create the default response with a wildcard mediatype - MediaType mediaType = new MediaTypeImpl().schema(createSchema(context, method.getReturnType())); + MediaType mediaType = new MediaTypeImpl().schema(createSchema(context, method.getReturnType(), method.getGenericReturnType())); defaultResponse.getContent().addMediaType(javax.ws.rs.core.MediaType.WILDCARD, mediaType); // Add the default response @@ -1010,19 +1014,22 @@ private static String getContentType(String name) { return contentType; } - private org.eclipse.microprofile.openapi.models.media.Schema createSchema(ApiContext context, Class type) { + private org.eclipse.microprofile.openapi.models.media.Schema createSchema(ApiContext context, Class type, Type genericType) { org.eclipse.microprofile.openapi.models.media.Schema schema = new SchemaImpl(); SchemaType schemaType = ModelUtils.getSchemaType(type); schema.setType(schemaType); // Set the subtype if it's an array (for example an array of ints) if (schemaType == SchemaType.ARRAY) { - Class subType = type.getComponentType(); - org.eclipse.microprofile.openapi.models.media.Schema subSchema = schema; - while (subType != null) { - subSchema.setItems(new SchemaImpl().type(ModelUtils.getSchemaType(subType))); - subSchema = schema.getItems(); - subType = subType.getComponentType(); + if (type.isArray()) { + schema.setItems(createSchema(context, type.getComponentType(), type.getComponentType())); + } else { // should be something Iterable + ParameterizedType fullType = (ParameterizedType) genericType; + Type genericElementType = fullType.getActualTypeArguments()[0]; + Class rawElementType = (Class) (genericElementType.getClass() == Class.class + ? genericElementType + : ((ParameterizedType)genericElementType).getRawType()); + schema.setItems(createSchema(context, rawElementType, genericElementType)); } } @@ -1038,7 +1045,7 @@ private org.eclipse.microprofile.openapi.models.media.Schema createSchema(ApiCon } private org.eclipse.microprofile.openapi.models.media.Schema createSchema(ApiContext context, - AnnotatedElement annotatedElement, Class type) { + AnnotatedElement annotatedElement, Class type, Type genericType) { SchemaType schemaType = ModelUtils.getSchemaType(type); // If the annotated element is the same type as the reference class, return a null schema @@ -1048,7 +1055,7 @@ private org.eclipse.microprofile.openapi.models.media.Schema createSchema(ApiCon schema.setItems(null); return schema; } - return createSchema(context, type); + return createSchema(context, type, genericType); } /** diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ReferenceTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ReferenceTest.java new file mode 100644 index 00000000000..2c6912ad373 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/ReferenceTest.java @@ -0,0 +1,63 @@ +package fish.payara.microprofile.openapi.test.app.application; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.Arrays; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +import fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest; +import fish.payara.microprofile.openapi.test.util.JsonUtils; + + +/** + * In response to {@link https://github.com/payara/Payara/issues/3832} this test should make sure the + * {@link org.eclipse.microprofile.openapi.models.media.Schema} is constructed and rendered correctly for the example + * given. + */ +@Path("/servers") +public class ReferenceTest extends OpenApiApplicationTest { + + @Schema(name = "Server") + public class Server { + @Schema(name = "name", required = true) + private String name; + + public Server(String name) { + super(); + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public List getServers() { + return Arrays.asList(new Server("Server A"), new Server("Server B")); + } + + @Test + public void test() { + JsonNode items = JsonUtils.path(getOpenAPIJson(), + "paths./test/servers.get.responses.default.content.application/json.schema.items"); + assertNotNull(items); + assertEquals("'#/components/schemas/Server'", items.get("$ref").textValue()); + } +} From 1a37fb52b5a198d69fc8f992657608564f34ca10 Mon Sep 17 00:00:00 2001 From: arjantijms Date: Thu, 21 Mar 2019 01:32:37 +0100 Subject: [PATCH 056/108] Revert "QA-171 Ignoring test until fixed" This reverts commit 37f39f6b4b594991736d770d98050432a663dbe3. --- appserver/tests/quicklook/testng/testng_gd.xml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/appserver/tests/quicklook/testng/testng_gd.xml b/appserver/tests/quicklook/testng/testng_gd.xml index 3334009287f..89f1dd2570a 100644 --- a/appserver/tests/quicklook/testng/testng_gd.xml +++ b/appserver/tests/quicklook/testng/testng_gd.xml @@ -41,14 +41,14 @@ --> - + - + @@ -70,7 +70,7 @@ - + @@ -126,13 +126,11 @@ - @@ -143,7 +141,7 @@ - + @@ -170,7 +168,7 @@ - + 2.2.0 - 2.7.4.payara-p1 + 2.7.4.payara-p2 1.2.1 From a8dfed9fc91047cb062f22c819e9fd61157cc0e1 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Thu, 21 Mar 2019 17:47:56 +0100 Subject: [PATCH 066/108] PAYARA-3466 added tests on the responses package --- .../impl/model/ResponsesBuilderTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ResponsesBuilderTest.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ResponsesBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ResponsesBuilderTest.java new file mode 100644 index 00000000000..3a93b049cae --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ResponsesBuilderTest.java @@ -0,0 +1,44 @@ +package fish.payara.microprofile.openapi.impl.model; + +import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; +import static org.eclipse.microprofile.openapi.OASFactory.createAPIResponse; +import static org.eclipse.microprofile.openapi.OASFactory.createContent; +import static org.eclipse.microprofile.openapi.OASFactory.createHeader; +import static org.eclipse.microprofile.openapi.OASFactory.createLink; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +/** + * Checks the JSON rendering of {@link fish.payara.microprofile.openapi.impl.model.responses.*}. + */ +public class ResponsesBuilderTest extends OpenApiBuilderTest { + + @Override + protected void setupBaseDocument(OpenAPI document) { + document.getComponents().addResponse("response1", createAPIResponse() + .description("description") + .addHeader("header1", createHeader().ref("ref")) + .addLink("link1", createLink().ref("ref")) + .addExtension("x-ext", "ext-value") + .content(createContent()) + ); + } + + @Test + public void pathHasExpectedFields() { + JsonNode response = path(getOpenAPIJson(), "components.responses.response1"); + assertNotNull(response); + assertEquals("description", response.get("description").textValue()); + assertEquals("ext-value", response.get("x-ext").textValue()); + assertTrue(response.get("headers").isObject()); + assertTrue(response.get("headers").get("header1").isObject()); + assertTrue(response.get("links").isObject()); + assertTrue(response.get("links").get("link1").isObject()); + } +} From 5a3d737f0679e1fe05310c7c3341368916c2ca01 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Thu, 21 Mar 2019 17:58:04 +0100 Subject: [PATCH 067/108] PAYARA-3466 started adding tests for the media package --- .../openapi/impl/model/MediaBuilderTest.java | 62 +++++++++++++++++++ .../impl/model/OperationsBuilderTest.java | 3 +- .../openapi/impl/model/SchemaBuilderTest.java | 34 ---------- .../impl/model/ServersBuilderTest.java | 3 +- 4 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java delete mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SchemaBuilderTest.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java new file mode 100644 index 00000000000..6fa665b2cb6 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java @@ -0,0 +1,62 @@ +package fish.payara.microprofile.openapi.impl.model; + +import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; +import static org.eclipse.microprofile.openapi.OASFactory.createSchema; +import static org.eclipse.microprofile.openapi.OASFactory.createXML; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.media.Schema.SchemaType; +import org.eclipse.microprofile.openapi.models.media.XML; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +/** + * Checks the JSON rendering of {@link fish.payara.microprofile.openapi.impl.model.media.*}. + */ +public class MediaBuilderTest extends OpenApiBuilderTest { + + @Override + protected void setupBaseDocument(OpenAPI document) { + document.getComponents().addSchema("SimpleMap", createSchema() + .type(SchemaType.OBJECT) + .additionalPropertiesSchema(createSchema().type(SchemaType.STRING))); + + XML xml = createXML() + .name("name") + .namespace("namespace") + .prefix("prefix") + .attribute(true) + .wrapped(true) + .addExtension("x-ext", "ext-value"); + + document.getComponents().addSchema("XML", createSchema() + .xml(xml)); + + } + + @Test + public void simpleMapSchemaHasExpectedFields() { + JsonNode mapEntry = path(getOpenAPIJson(), "components.schemas.SimpleMap"); + assertNotNull(mapEntry); + assertEquals("object", mapEntry.get("type").textValue()); + JsonNode additionalProperties = mapEntry.get("additionalProperties"); + assertNotNull(additionalProperties); + assertEquals("string", additionalProperties.get("type").textValue()); + } + + @Test + public void xmlHasExpectedFields() { + JsonNode xml = path(getOpenAPIJson(), "components.schemas.XML.xml"); + assertNotNull(xml); + assertEquals("name", xml.get("name").textValue()); + assertEquals("namespace", xml.get("namespace").textValue()); + assertEquals("prefix", xml.get("prefix").textValue()); + assertEquals("ext-value", xml.get("x-ext").textValue()); + assertTrue(xml.get("attribute").booleanValue()); + assertTrue(xml.get("wrapped").booleanValue()); + } +} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OperationsBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OperationsBuilderTest.java index a486ff26242..c1bb2011aac 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OperationsBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OperationsBuilderTest.java @@ -21,8 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode; /** - * Checks the JSON rendering of {@link fish.payara.microprofile.openapi.impl.model.OperationImpl} and - * {@link fish.payara.microprofile.openapi.impl.model.ExternalDocumentationImpl}. + * Checks the JSON rendering of {@link OperationImpl} and {@link ExternalDocumentationImpl}. */ public class OperationsBuilderTest extends OpenApiBuilderTest { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SchemaBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SchemaBuilderTest.java deleted file mode 100644 index 4cdc9908f8c..00000000000 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SchemaBuilderTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package fish.payara.microprofile.openapi.impl.model; - -import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; -import static org.eclipse.microprofile.openapi.OASFactory.createSchema; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.eclipse.microprofile.openapi.models.OpenAPI; -import org.eclipse.microprofile.openapi.models.media.Schema.SchemaType; -import org.junit.Test; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -public class SchemaBuilderTest extends OpenApiBuilderTest { - - @Override - protected void setupBaseDocument(OpenAPI document) { - document.getComponents().getSchemas().put("SimpleMap", createSchema() - .type(SchemaType.OBJECT) - .additionalPropertiesSchema(createSchema().type(SchemaType.STRING))); - } - - @Test - public void schemaHasExpectedFields() { - ObjectNode openAPI = getOpenAPIJson(); - JsonNode mapEntry = path(openAPI, "components.schemas.SimpleMap"); - assertNotNull(mapEntry); - assertEquals("object", mapEntry.get("type").textValue()); - JsonNode additionalProperties = mapEntry.get("additionalProperties"); - assertNotNull(additionalProperties); - assertEquals("string", additionalProperties.get("type").textValue()); - } -} diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ServersBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ServersBuilderTest.java index 0bda52b82b0..1b956bd53c1 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ServersBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ServersBuilderTest.java @@ -14,8 +14,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode; /** - * Checks the JSON rendering of {@link fish.payara.microprofile.openapi.impl.model.servers.ServerImpl} and - * {@link fish.payara.microprofile.openapi.impl.model.servers.ServerVariableImpl}. + * Checks the JSON rendering of {@link fish.payara.microprofile.openapi.impl.model.servers.*}. */ public class ServersBuilderTest extends OpenApiBuilderTest { From dc603a6f77911454ac38de720b4a86438d14e9fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Dudit=C5=A1?= Date: Fri, 22 Mar 2019 11:28:15 +0100 Subject: [PATCH 068/108] Removing static modifiers --- .../main/java/org/glassfish/ejb/config/EjbTimerService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appserver/ejb/ejb-connector/src/main/java/org/glassfish/ejb/config/EjbTimerService.java b/appserver/ejb/ejb-connector/src/main/java/org/glassfish/ejb/config/EjbTimerService.java index e513e7f2543..0f59488e240 100644 --- a/appserver/ejb/ejb-connector/src/main/java/org/glassfish/ejb/config/EjbTimerService.java +++ b/appserver/ejb/ejb-connector/src/main/java/org/glassfish/ejb/config/EjbTimerService.java @@ -68,8 +68,8 @@ @Configured public interface EjbTimerService extends ConfigBeanProxy, PropertyBag { - static String TYPE_NONE = "None"; - static String TYPE_DATABASE = "Database"; + String TYPE_NONE = "None"; + String TYPE_DATABASE = "Database"; /** * Gets the value of the minimumDeliveryIntervalInMillis property. From 2301d99c5d3c169b717a33a6d5f14fdb65634b0c Mon Sep 17 00:00:00 2001 From: mertcaliskan Date: Sun, 24 Mar 2019 10:42:07 +0300 Subject: [PATCH 069/108] PAYARA-3706-Upgrade-hibernate-validator-to-6.0.16.Final --- nucleus/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nucleus/pom.xml b/nucleus/pom.xml index b18bfb51010..df1de015d37 100644 --- a/nucleus/pom.xml +++ b/nucleus/pom.xml @@ -266,8 +266,8 @@ 2.0.1.Final - 6.0.15.Final - 6.0.15.Final + 6.0.16.Final + 6.0.16.Final 3.0.1-b11 From 6488cbdc90fd0f6c42de6a42affcd09f697be715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Dudit=C5=A1?= Date: Mon, 25 Mar 2019 21:16:52 +0100 Subject: [PATCH 070/108] PAYARA-3386: Update login.conf with login module (#3837) * PAYARA-3386: Document contract of realm property jaas-context * PAYARA-3386: Automatically add login module to login.conf for custom modules * PAYARA-3386: Pre-fill default JAAS contexts for given realm type * PAYARA-3386: Admin UI for registering login module * PAYARA-3386: Cleanup method saveRealm Handling of property maps as list of maps extracted to helper class * PAYARA-3386: Implement --login-module switch in saveRealm handler * PAYARA-3386: Clean up formatting of PropertyList * PAYARA-3386: Update licenses * prepare merge * PAYARA-3386 re-apply stashed changes after merge master * PAYARA-3386: More strict UI validation --- .../common/handlers/PropertyList.java | 135 ++++++++++++++++++ .../common/handlers/SecurityHandler.java | 85 +++++------ .../common/admingui/Strings.properties | 7 +- .../resources/security/realms/realmAttrs.inc | 38 ++++- .../security/realms/realmButtons.inc | 2 +- .../resources/security/realms/realmjs.inc | 40 +++++- .../sun/enterprise/security/BaseRealm.java | 12 +- .../auth/realm/AbstractStatefulRealm.java | 7 +- .../enterprise/security/auth/realm/Realm.java | 6 + .../security/cli/CreateAuthRealm.java | 63 +++++++- 10 files changed, 338 insertions(+), 57 deletions(-) create mode 100644 appserver/admingui/common/src/main/java/org/glassfish/admingui/common/handlers/PropertyList.java diff --git a/appserver/admingui/common/src/main/java/org/glassfish/admingui/common/handlers/PropertyList.java b/appserver/admingui/common/src/main/java/org/glassfish/admingui/common/handlers/PropertyList.java new file mode 100644 index 00000000000..635b1b9fc7a --- /dev/null +++ b/appserver/admingui/common/src/main/java/org/glassfish/admingui/common/handlers/PropertyList.java @@ -0,0 +1,135 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + **/ + +package org.glassfish.admingui.common.handlers; + +import org.glassfish.admingui.common.util.GuiUtil; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Type representing properties as List of Maps. + */ +class PropertyList implements Iterable> { + private Map properties = new LinkedHashMap<>(); + + private PropertyList() { + + } + + void put(String key, String value) { + if (GuiUtil.isEmpty(key)) { + return; + } + if (!GuiUtil.isEmpty(value)) { + properties.put(key, value); + } + } + + void put(String key, Map sourceMap, String sourceKey) { + if (sourceMap != null) { + put(key, sourceMap.get(sourceKey)); + } + } + + public int size() { + return properties.size(); + } + + public boolean isEmpty() { + return properties.isEmpty(); + } + + public boolean containsKey(Object key) { + return properties.containsKey(key); + } + + public String get(Object key) { + return properties.get(key); + } + + @Override + public Iterator> iterator() { + return properties.entrySet().iterator(); + } + + public List> toList() { + return properties.entrySet().stream() + .map(e -> toPropertyEntry(e.getKey(), e.getValue())) + .collect(Collectors.toList()); + } + + public String toParamValue() { + StringBuilder paramValue = new StringBuilder(); + for (Map.Entry oneProp : this) { + paramValue.append(oneProp.getKey()).append("="); + String value = oneProp.getValue().replaceAll("\\\\", "\\\\\\\\"); + value = UtilHandlers.escapePropertyValue(value); + paramValue.append(value).append(":"); + } + return paramValue.toString(); + } + + static Map toPropertyEntry(String name, String value) { + Map result = new HashMap<>(); + result.put("name", name); + result.put("value", value); + return result; + } + + static PropertyList fromList(List> propertyList) { + PropertyList result = new PropertyList(); + for (Map entry : propertyList) { + result.put(entry.get("name"), entry.get("value")); + } + return result; + } + + static PropertyList fromMap(Map map) { + PropertyList result = new PropertyList(); + result.properties.putAll(map); + return result; + } +} diff --git a/appserver/admingui/common/src/main/java/org/glassfish/admingui/common/handlers/SecurityHandler.java b/appserver/admingui/common/src/main/java/org/glassfish/admingui/common/handlers/SecurityHandler.java index b75e63d99d7..e1ce8c2ddb0 100644 --- a/appserver/admingui/common/src/main/java/org/glassfish/admingui/common/handlers/SecurityHandler.java +++ b/appserver/admingui/common/src/main/java/org/glassfish/admingui/common/handlers/SecurityHandler.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package org.glassfish.admingui.common.handlers; @@ -82,7 +82,12 @@ public static void getRealmAttrForCreate(HandlerContext handlerCtx) { handlerCtx.setOutputValue("realmClasses", realmClassList); handlerCtx.setOutputValue("classnameOption", "predefine"); Map attrMap = new HashMap(); + attrMap.put("fileJaax", "fileRealm"); + attrMap.put("ldapJaax", "ldapRealm" ); + attrMap.put("solarisJaax", "solarisRealm"); + attrMap.put("jdbcJaax", "jdbcRealm"); attrMap.put("predefinedClassname", Boolean.TRUE); + attrMap.put("createNew", true); handlerCtx.setOutputValue("attrMap", attrMap); handlerCtx.setOutputValue("properties", new ArrayList()); } @@ -237,7 +242,7 @@ public static List getListfromMap(HashMap props) { public static void saveRealm(HandlerContext handlerCtx) { String option = (String) handlerCtx.getInputValue("classnameOption"); List> propListOrig = (List)handlerCtx.getInputValue("propList"); - List> propList = new ArrayList(propListOrig); + PropertyList propList = PropertyList.fromList(propListOrig); Map attrMap = (Map)handlerCtx.getInputValue("attrMap"); Boolean edit = (Boolean) handlerCtx.getInputValue("edit"); @@ -250,71 +255,69 @@ public static void saveRealm(HandlerContext handlerCtx) { classname = attrMap.get("classname"); if(classname.indexOf("FileRealm")!= -1){ - putOptional(attrMap, propList, "file", "file"); - putOptional(attrMap, propList, "jaas-context", "fileJaax"); - putOptional(attrMap, propList, "assign-groups", "fileAsGroups"); + propList.put( "file", attrMap, "file"); + propList.put( "jaas-context", attrMap, "fileJaax"); + propList.put( "assign-groups", attrMap, "fileAsGroups"); }else if(classname.indexOf("LDAPRealm")!= -1){ - putOptional(attrMap, propList, "jaas-context", "ldapJaax"); - putOptional(attrMap, propList, "base-dn", "baseDn"); - putOptional(attrMap, propList, "directory", "directory"); - putOptional(attrMap, propList, "assign-groups", "ldapAsGroups"); + propList.put( "jaas-context", attrMap, "ldapJaax"); + propList.put( "base-dn", attrMap, "baseDn"); + propList.put( "directory", attrMap, "directory"); + propList.put( "assign-groups", attrMap, "ldapAsGroups"); }else if(classname.indexOf("SolarisRealm")!= -1){ - putOptional(attrMap, propList, "jaas-context", "solarisJaax"); - putOptional(attrMap, propList, "assign-groups", "solarisAsGroups"); + propList.put( "jaas-context", attrMap, "solarisJaax"); + propList.put( "assign-groups", attrMap, "solarisAsGroups"); }else if(classname.indexOf("PamRealm")!= -1){ - putOptional(attrMap, propList, "jaas-context", "pamJaax"); + propList.put( "jaas-context", attrMap, "pamJaax"); }else if(classname.indexOf("JDBCRealm")!= -1){ - putOptional(attrMap, propList, "jaas-context", "jdbcJaax"); - putOptional(attrMap, propList, "datasource-jndi", "datasourceJndi"); - putOptional(attrMap, propList, "user-table", "userTable"); - putOptional(attrMap, propList, "user-name-column", "userNameColumn"); - putOptional(attrMap, propList, "password-column", "passwordColumn"); - putOptional(attrMap, propList, "group-table", "groupTable"); - putOptional(attrMap, propList, "group-table-user-name-column", "groupTableUserName"); - putOptional(attrMap, propList, "group-name-column", "groupNameColumn"); - putOptional(attrMap, propList, "db-user", "dbUser"); - putOptional(attrMap, propList, "db-password", "dbPassword"); - putOptional(attrMap, propList, "digest-algorithm", "digestAlgorithm"); - putOptional(attrMap, propList, "digestrealm-password-enc-algorithm", "pswdEncAlgorithm"); - putOptional(attrMap, propList, "encoding", "encoding"); - putOptional(attrMap, propList, "charset", "charset"); - putOptional(attrMap, propList, "assign-groups", "jdbcAsGroups"); + propList.put( "jaas-context", attrMap, "jdbcJaax"); + propList.put( "datasource-jndi", attrMap, "datasourceJndi"); + propList.put( "user-table", attrMap, "userTable"); + propList.put( "user-name-column", attrMap, "userNameColumn"); + propList.put( "password-column", attrMap, "passwordColumn"); + propList.put( "group-table", attrMap, "groupTable"); + propList.put( "group-table-user-name-column", attrMap, "groupTableUserName"); + propList.put( "group-name-column", attrMap, "groupNameColumn"); + propList.put( "db-user", attrMap, "dbUser"); + propList.put( "db-password", attrMap, "dbPassword"); + propList.put( "digest-algorithm", attrMap, "digestAlgorithm"); + propList.put( "digestrealm-password-enc-algorithm", attrMap, "pswdEncAlgorithm"); + propList.put( "encoding", attrMap, "encoding"); + propList.put( "charset", attrMap, "charset"); + propList.put( "assign-groups", attrMap, "jdbcAsGroups"); }else { if(classname.indexOf("CertificateRealm")!= -1){ - putOptional(attrMap, propList, "assign-groups", "certAsGroups"); + propList.put( "assign-groups", attrMap, "certAsGroups"); } } } else { classname = attrMap.get("classnameInput"); } - String endpoint = (String) handlerCtx.getInputValue("endpoint"); //for edit case, only properties will be changed since we don't allow classname change. //return the prop list so it can continue processing in the .jsf if (edit){ - handlerCtx.setOutputValue("newPropList", propList); + handlerCtx.setOutputValue("newPropList", propList.toList()); return; } + Map cMap = new HashMap(); cMap.put("name", attrMap.get("Name")); cMap.put("classname", classname); - StringBuilder sb = new StringBuilder(); - for(Map oneProp: propList) { - if (GuiUtil.isEmpty( (String)oneProp.get("name")) || GuiUtil.isEmpty((String)oneProp.get("value"))){ - continue; - } - sb.append(oneProp.get("name")).append("="); - String value = ((String) oneProp.get("value")).replaceAll("\\\\", "\\\\\\\\"); - value = UtilHandlers.escapePropertyValue(value); - sb.append(value).append(":"); + cMap.put(TARGET, attrMap.get(TARGET)); + + if (Boolean.parseBoolean(attrMap.get("registerLoginModule"))) { + propList.put("jaas-context", attrMap, "loginModuleJaax"); + cMap.put("login-module", attrMap.get("loginModuleClass")); } + + cMap.put("property", propList.toParamValue()); + + String endpoint = (String) handlerCtx.getInputValue("endpoint"); endpoint = endpoint + "/auth-realm"; - cMap.put(TARGET, attrMap.get(TARGET)); - cMap.put("property", sb.toString()); RestUtil.restRequest(endpoint, cMap, "post", handlerCtx, false); }catch(Exception ex){ GuiUtil.handleException(handlerCtx, ex); diff --git a/appserver/admingui/common/src/main/resources/org/glassfish/common/admingui/Strings.properties b/appserver/admingui/common/src/main/resources/org/glassfish/common/admingui/Strings.properties index fcc5f79f2f0..1d1e81914d7 100644 --- a/appserver/admingui/common/src/main/resources/org/glassfish/common/admingui/Strings.properties +++ b/appserver/admingui/common/src/main/resources/org/glassfish/common/admingui/Strings.properties @@ -37,7 +37,7 @@ # only if the new code is made subject to such option by the copyright # holder. # -# Portions Copyright [2016-2018] [Payara Foundation and/or its affiliates] +# Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] ## 'server' is the name of the server instance. No Not Translate it. tree.adminServer=server (Admin Server) @@ -154,6 +154,11 @@ realm.encodingHelp=Encoding (allowed values are Hex and Base64) realm.charset=Charset: realm.charsetHelp=Character set for the digest algorithm realm.internalError=Internal error. No realm name specified. +realm.loginmodule.register=Register Login Module: +realm.loginmodule.help=Update JAAS configuration in login.conf (when using non-default JAAS context of standard realm, or custom realm) +realm.loginmodule.jaaxNote=(passed as property jaas-context to realm) +realm.loginmodule.class=Login Module Class: +realm.loginmodule.classHelp=Class name of the login module ## Audit Modules auditModule.TableTitle=Modules diff --git a/appserver/admingui/common/src/main/resources/security/realms/realmAttrs.inc b/appserver/admingui/common/src/main/resources/security/realms/realmAttrs.inc index 177d398df6f..0922bf3eac9 100644 --- a/appserver/admingui/common/src/main/resources/security/realms/realmAttrs.inc +++ b/appserver/admingui/common/src/main/resources/security/realms/realmAttrs.inc @@ -38,7 +38,7 @@ only if the new code is made subject to such option by the copyright holder. - Portions Copyright [2017] Payara Foundation and/or affiliates + Portions Copyright [2017-2019] Payara Foundation and/or affiliates --> @@ -194,3 +194,39 @@ + + + $page{loginModuleSection}); + /> + + + $page{registerLoginModule}); + /> + + + + $page{loginModuleJaax}); + /> + + + + + + + + + + \ No newline at end of file diff --git a/appserver/admingui/common/src/main/resources/security/realms/realmButtons.inc b/appserver/admingui/common/src/main/resources/security/realms/realmButtons.inc index 9dac77ed4c1..759cf80430d 100644 --- a/appserver/admingui/common/src/main/resources/security/realms/realmButtons.inc +++ b/appserver/admingui/common/src/main/resources/security/realms/realmButtons.inc @@ -62,7 +62,7 @@ + onClick="if (checkForm()) {submitAndDisable(this, '$resource{i18n.button.Processing}');}; return false;" > $attribute{tableRowGroup}); getAllSingleMapRows(TableRowGroup="$attribute{tableRowGroup}", Rows=>$attribute{newList}); diff --git a/appserver/admingui/common/src/main/resources/security/realms/realmjs.inc b/appserver/admingui/common/src/main/resources/security/realms/realmjs.inc index 77c0b070313..51609deed99 100644 --- a/appserver/admingui/common/src/main/resources/security/realms/realmjs.inc +++ b/appserver/admingui/common/src/main/resources/security/realms/realmjs.inc @@ -38,7 +38,7 @@ only if the new code is made subject to such option by the copyright holder. - Portions Copyright [2017] Payara Foundation and/or affiliates + Portions Copyright [2017-2019] Payara Foundation and/or affiliates --> @@ -51,7 +51,8 @@ #{themeJavascript.JS_PREFIX}.radiobutton.setChecked('#{rbPropId}:optB', true); }else{ #{themeJavascript.JS_PREFIX}.radiobutton.setChecked('#{rbPropId}:optA', true); - } + } + toggleLoginModule(#{attrMap.registerLoginModule}); } function enableClassnameFields(opt, createFlag){ @@ -73,6 +74,17 @@ } } +function checkForm() { + return checkLoginModule() && checkClassname(); +} + +function checkLoginModule() { + if (isChecked('form1:loginModuleSection:registerLoginModule:registerLoginModule')) { + return checkRequired('form1:loginModuleSection:loginModule:loginModule', '#{reqMsg}'); + } + return true; +} + function checkClassname() { var opt = getSelectedValueFromForm(document.forms['form1'], 'classnameOption'); if (opt == 'predefine') { @@ -111,6 +123,18 @@ function checkClassname() { } } +function toggleLoginModule(value) { + var section = document.getElementById('#{loginModuleSection}'); + var enabled = "login-module-enabled"; + var disabled = "login-module-disabled"; + var className = section.className; + if (value) { + section.className = className.replace(disabled, enabled); + } else { + section.className = className.replace(enabled, disabled); + } +} + function showDisplay(testtype) { document.getElementById('#{fileSectionId}').style.display = 'none'; document.getElementById('#{ldapSectionId}').style.display = 'none'; @@ -118,8 +142,12 @@ function showDisplay(testtype) { document.getElementById('#{certSectionId}').style.display = 'none'; document.getElementById('#{solarisSectionId}').style.display = 'none'; document.getElementById('#{pamSectionId}').style.display = 'none'; - - if (testtype.match('none')){ + var loginModuleJaax = document.getElementById('#{loginModuleJaax}'); + + loginModuleJaax.className = 'not-required'; + + if (testtype.match('none')){ + loginModuleJaax.className = 'required'; return; } type = getSelectElement('#{classnameDropdownId}').value; @@ -145,7 +173,9 @@ function showDisplay(testtype) { } rtype = type.match('CertificateRealm'); if (rtype != null){ - document.getElementById('#{certSectionId}').style.display = 'block'; + document.getElementById('#{certSectionId}').style.display = 'block'; + // strangely enough, certificate realm does not have JAAS context property + loginModuleJaax.className = 'required'; return; } rtype = type.match('PamRealm'); diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseRealm.java index 752e5ee71e0..6bd019ce194 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseRealm.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/BaseRealm.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security; import java.util.*; @@ -59,7 +59,13 @@ * @author Harpreet Singh */ public abstract class BaseRealm extends Realm { - public static final String JAAS_CONTEXT_PARAM = "jaas-context"; + /** + * Recommended property for keeping JAAS Context of a realm. + * + * @deprecated Moved to parent class, which actually implements the behaviour + */ + @Deprecated + public static final String JAAS_CONTEXT_PARAM = Realm.JAAS_CONTEXT_PARAM; protected static final StringManager sm = StringManager.getManager(Realm.class); @@ -180,7 +186,7 @@ public void updateUser(String name, String newName, String password, String[] gr * name which does not already exist as a user. * @param password Cleartext password for the user. If non-null the user password is changed to this value. If null, the * original password is retained. - * @param groupList List of groups to which user belongs. + * @param groups List of groups to which user belongs. * @throws BadRealmException If there are problems adding user. * @throws NoSuchUserException If user does not exist. * diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AbstractStatefulRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AbstractStatefulRealm.java index 7645f578f82..11d0f43e759 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AbstractStatefulRealm.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/AbstractStatefulRealm.java @@ -40,7 +40,7 @@ // Portions Copyright [2018-2019] Payara Foundation and/or affiliates package com.sun.enterprise.security.auth.realm; -import static com.sun.enterprise.security.BaseRealm.JAAS_CONTEXT_PARAM; +import static com.sun.enterprise.security.auth.realm.Realm.JAAS_CONTEXT_PARAM; import static com.sun.enterprise.security.auth.realm.RealmsManagerStore._getRealmsManager; import java.util.ArrayList; @@ -232,7 +232,10 @@ protected synchronized Properties getProperties() { * Returns name of JAAS context used by this realm. * *

    - * The JAAS context is defined in server.xml auth-realm element associated with this realm. + * JAAS context determines the login module(s) to be invoked by means of JAAS configuration file ({@code login.conf} + * in domain config directory). + *

    + * Default implementation uses value of realm's property {@code jaas-context}. * * @return String containing JAAS context name. * diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java index d8db7c8b8fb..310e897e150 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/auth/realm/Realm.java @@ -74,6 +74,12 @@ */ @Contract public abstract class Realm extends AbstractStatefulRealm implements Comparable { + /** + * Recommended property for keeping JAAS Context of a realm. + * + * @see #getJAASContext() + */ + public static final String JAAS_CONTEXT_PARAM = "jaas-context"; protected static final Logger _logger = SecurityLoggerInfo.getLogger(); private static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(Realm.class); diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateAuthRealm.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateAuthRealm.java index 8f18103fd87..c519be7659d 100644 --- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateAuthRealm.java +++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/cli/CreateAuthRealm.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.cli; import static com.sun.enterprise.security.cli.CLIUtil.chooseConfig; @@ -45,17 +45,21 @@ import static com.sun.enterprise.util.SystemPropertyConstants.DEFAULT_SERVER_INSTANCE_NAME; import static org.glassfish.api.ActionReport.ExitCode.FAILURE; import static org.glassfish.api.ActionReport.ExitCode.SUCCESS; +import static org.glassfish.api.ActionReport.ExitCode.WARNING; import static org.glassfish.config.support.CommandTarget.CLUSTER; import static org.glassfish.config.support.CommandTarget.CONFIG; import static org.glassfish.config.support.CommandTarget.DAS; import static org.glassfish.config.support.CommandTarget.STANDALONE_INSTANCE; import java.beans.PropertyVetoException; +import java.io.FileWriter; +import java.io.IOException; import java.util.Properties; -import java.util.Set; import javax.inject.Inject; import javax.inject.Named; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; import org.glassfish.api.ActionReport; import org.glassfish.api.I18n; @@ -67,7 +71,6 @@ import org.glassfish.api.admin.ExecuteOn; import org.glassfish.api.admin.RuntimeType; import org.glassfish.api.admin.ServerEnvironment; -import org.glassfish.config.support.CommandTarget; import org.glassfish.config.support.TargetType; import org.glassfish.hk2.api.PerLookup; import org.jvnet.hk2.annotations.Service; @@ -128,6 +131,9 @@ public class CreateAuthRealm implements AdminCommand, AdminCommandSecurity.Preau @Param(name = "target", optional = true, defaultValue = DEFAULT_SERVER_INSTANCE_NAME) private String target; + @Param(name = "login-module", optional = true) + private String loginModule; + @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME) private Config config; @@ -179,6 +185,13 @@ public Object run(SecurityService param) throws PropertyVetoException, Transacti return newAuthRealm; } }, securityService); + if (loginModule != null) { + appendLoginModule(report); + if (report.hasFailures()) { + report.setActionExitCode(WARNING); + return; + } + } } catch (TransactionFailure e) { report.setMessage( localStrings.getLocalString( @@ -193,6 +206,50 @@ public Object run(SecurityService param) throws PropertyVetoException, Transacti report.setActionExitCode(SUCCESS); } + private void appendLoginModule(ActionReport mainReport) { + ActionReport report = mainReport.addSubActionsReport(); + report.setActionDescription("Updating login config"); + + String loginConfLocation = System.getProperty("java.security.auth.login.config"); + if (loginConfLocation == null) { + report.appendMessage(localStrings.getLocalString("create.auth.realm.loginconf.undefined", + "JDK default login config is set. Cannot update")); + report.setActionExitCode(FAILURE); + return; + } + + String jaasContext = properties.getProperty("jaas-context"); + if (jaasContext == null || jaasContext.isEmpty()) { + report.appendMessage(localStrings.getLocalString("create.auth.realm.loginconf.nojaasctx", + "No JAAS context is defined for login module")); + report.setActionExitCode(FAILURE); + return; + } + + try { + new LoginContext(jaasContext); + report.appendMessage(localStrings.getLocalString("create.auth.realm.loginconf.jaasctx.already.defined", + "JAAS context {0} is already configured", jaasContext)); + report.setActionExitCode(FAILURE); + return; + } catch (LoginException e) { + // Login Context will throw when initialized with unknown jaas context, which is exactly what we need. + } + + try (FileWriter fw = new FileWriter(loginConfLocation, true)) { + fw.append("\n") + .append(jaasContext).append(" {\n") + .append("\t").append(loginModule).append(" required;\n") + .append("};"); + + } catch (IOException e) { + report.appendMessage(localStrings.getLocalString("create.auth.realm.loginconf.write_failed", + "Failed to update login conf at {0}: {1}", loginConfLocation, e.getLocalizedMessage())); + report.setFailureCause(e); + report.setActionExitCode(FAILURE); + } + } + private void populateAuthRealmElement(AuthRealm newAuthRealm) throws PropertyVetoException, TransactionFailure { newAuthRealm.setName(authRealmName); newAuthRealm.setClassname(className); From 05a0ba25583230354d8827ca632a85b7a8e1c877 Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Tue, 12 Mar 2019 20:24:31 +0100 Subject: [PATCH 071/108] PAYARA-3540: Use no-fork javadoc invocation and package the jar manually --- pom.xml | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index b351acaa69b..09b74772624 100644 --- a/pom.xml +++ b/pom.xml @@ -68,9 +68,10 @@ 1.6 2.5.2 - 3.0.1 + 3.1.0 3.0.1 2.8.2 + UTF-8 @@ -194,18 +195,42 @@ aggregate - aggregate - aggregate-jar + aggregate-no-fork + + pre-site payara-5.192-SNAPSHOT + 512m + 2g + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + javadoc-jar + + jar + + pre-site + + ${project.build.directory}/site/apidocs + javadoc + payara-${project.version} From 14cd520f3761ec04441b6be0c804eced90db688e Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 26 Mar 2019 11:07:17 +0100 Subject: [PATCH 072/108] PAYARA-3466 added tests on media package types (except schema) --- .../openapi/impl/model/MediaBuilderTest.java | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java index 6fa665b2cb6..d90553b2d34 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java @@ -1,6 +1,13 @@ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; +import static org.eclipse.microprofile.openapi.OASFactory.createAPIResponse; +import static org.eclipse.microprofile.openapi.OASFactory.createContent; +import static org.eclipse.microprofile.openapi.OASFactory.createDiscriminator; +import static org.eclipse.microprofile.openapi.OASFactory.createEncoding; +import static org.eclipse.microprofile.openapi.OASFactory.createExample; +import static org.eclipse.microprofile.openapi.OASFactory.createHeader; +import static org.eclipse.microprofile.openapi.OASFactory.createMediaType; import static org.eclipse.microprofile.openapi.OASFactory.createSchema; import static org.eclipse.microprofile.openapi.OASFactory.createXML; import static org.junit.Assert.assertEquals; @@ -8,6 +15,10 @@ import static org.junit.Assert.assertTrue; import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.media.Discriminator; +import org.eclipse.microprofile.openapi.models.media.Encoding; +import org.eclipse.microprofile.openapi.models.media.Encoding.Style; +import org.eclipse.microprofile.openapi.models.media.MediaType; import org.eclipse.microprofile.openapi.models.media.Schema.SchemaType; import org.eclipse.microprofile.openapi.models.media.XML; import org.junit.Test; @@ -36,6 +47,35 @@ protected void setupBaseDocument(OpenAPI document) { document.getComponents().addSchema("XML", createSchema() .xml(xml)); + Encoding encoding = createEncoding() + .contentType("contentType") + .style(Style.FORM) + .explode(true) + .allowReserved(true) + .addExtension("x-ext", "ext-value") + .addHeader("header1", createHeader().ref("ref1")) + .addHeader("header2", createHeader().ref("ref2")); + + MediaType mediaType = createMediaType() + .example("example") + .schema(createSchema().ref("ref")) + .addExtension("x-ext", "ext-value") + .addExample("example1", createExample().ref("ref1")) + .addExample("example2", createExample().ref("ref2")) + .addEncoding("encoding1", encoding); + + document.getComponents().addResponse("MediaType", createAPIResponse() + .description("description") + .content(createContent() + .addMediaType("type1", mediaType))); + + Discriminator discriminator = createDiscriminator() + .propertyName("propertyName") + .addMapping("key1", "value1") + .addMapping("key2", "value2"); + + document.getComponents().addSchema("Discriminator", createSchema() + .discriminator(discriminator)); } @Test @@ -59,4 +99,50 @@ public void xmlHasExpectedFields() { assertTrue(xml.get("attribute").booleanValue()); assertTrue(xml.get("wrapped").booleanValue()); } + + @Test + public void mediaTypeHasExpectedFields() { + JsonNode mediaType = path(getOpenAPIJson(), "components.responses.MediaType.content.type1"); + assertNotNull(mediaType); + assertEquals("example", mediaType.get("example").textValue()); + assertEquals("ext-value", mediaType.get("x-ext").textValue()); + assertTrue(mediaType.get("schema").isObject()); + JsonNode examples = mediaType.get("examples"); + assertTrue(examples.isObject()); + assertEquals(2, examples.size()); + assertTrue(examples.get("example1").isObject()); + assertTrue(examples.get("example2").isObject()); + JsonNode encodings = mediaType.get("encoding"); + assertTrue(encodings.isObject()); + assertEquals(1, encodings.size()); + assertTrue(encodings.get("encoding1").isObject()); + } + + @Test + public void encodingHasExpectedFields() { + JsonNode encoding = path(getOpenAPIJson(), "components.responses.MediaType.content.type1.encoding.encoding1"); + assertNotNull(encoding); + assertEquals("contentType", encoding.get("contentType").textValue()); + assertEquals("form", encoding.get("style").textValue()); + assertEquals("ext-value", encoding.get("x-ext").textValue()); + assertTrue(encoding.get("explode").booleanValue()); + assertTrue(encoding.get("allowReserved").booleanValue()); + JsonNode headers = encoding.get("headers"); + assertTrue(headers.isObject()); + assertEquals(2, headers.size()); + assertTrue(headers.get("header1").isObject()); + assertTrue(headers.get("header2").isObject()); + } + + @Test + public void discriminatorHasExpectedFields() { + JsonNode discriminator = path(getOpenAPIJson(), "components.schemas.Discriminator.discriminator"); + assertNotNull(discriminator); + assertEquals("propertyName", discriminator.get("propertyName").textValue()); + JsonNode mapping = discriminator.get("mapping"); + assertTrue(mapping.isObject()); + assertEquals(2, mapping.size()); + assertEquals("value1", mapping.get("key1").textValue()); + assertEquals("value2", mapping.get("key2").textValue()); + } } From 8ca48279737a9f4cafc28ba0630dd23b33eeaf2c Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 26 Mar 2019 12:14:31 +0100 Subject: [PATCH 073/108] PAYARA-3466 added tests on media package - Schema --- .../impl/processor/FilterProcessor.java | 3 +- .../openapi/impl/model/MediaBuilderTest.java | 102 ++++++++++++++++++ .../impl/model/ModelInvariantsTest.java | 22 ++++ .../rule/ApplicationProcessedDocument.java | 4 +- 4 files changed, 127 insertions(+), 4 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java index b115f5d280c..7aa2dff7048 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/FilterProcessor.java @@ -151,7 +151,8 @@ private Object filterObject(Object object) { } // If the object is a model item - if (object.getClass().getPackage().getName().startsWith(OpenAPIImpl.class.getPackage().getName())) { + Package pkg = object.getClass().getPackage(); + if (pkg != null && pkg.getName().startsWith(OpenAPIImpl.class.getPackage().getName())) { // Visit each field for (Field field : object.getClass().getDeclaredFields()) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java index d90553b2d34..6af69a31db0 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java @@ -6,6 +6,7 @@ import static org.eclipse.microprofile.openapi.OASFactory.createDiscriminator; import static org.eclipse.microprofile.openapi.OASFactory.createEncoding; import static org.eclipse.microprofile.openapi.OASFactory.createExample; +import static org.eclipse.microprofile.openapi.OASFactory.createExternalDocumentation; import static org.eclipse.microprofile.openapi.OASFactory.createHeader; import static org.eclipse.microprofile.openapi.OASFactory.createMediaType; import static org.eclipse.microprofile.openapi.OASFactory.createSchema; @@ -14,6 +15,8 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import java.math.BigDecimal; + import org.eclipse.microprofile.openapi.models.OpenAPI; import org.eclipse.microprofile.openapi.models.media.Discriminator; import org.eclipse.microprofile.openapi.models.media.Encoding; @@ -76,6 +79,49 @@ protected void setupBaseDocument(OpenAPI document) { document.getComponents().addSchema("Discriminator", createSchema() .discriminator(discriminator)); + + document.getComponents().addSchema("Schema", createSchema() + .title("title") + .multipleOf(BigDecimal.ONE) + .maximum(BigDecimal.ONE) + .exclusiveMaximum(true) + .minimum(BigDecimal.ONE) + .exclusiveMinimum(true) + .maxLength(10) + .minLength(1) + .pattern("pattern") + .maxItems(11) + .minItems(2) + .uniqueItems(true) + .maxProperties(12) + .minProperties(3) + .addRequired("required1") + .addRequired("required2") + .type(SchemaType.NUMBER) + .not(createSchema().ref("not")) + .addProperty("property1", createSchema().ref("property1")) + .description("description") + .format("format") + .nullable(true) + .readOnly(true) + .writeOnly(true) + .example("example") + .externalDocs(createExternalDocumentation().url("url")) + .deprecated(true) + .xml(xml) + .addEnumeration("enumeration1") + .addEnumeration("enumeration2") + .discriminator(discriminator) + .addAnyOf(createSchema().ref("anyOf1")) + .addAnyOf(createSchema().ref("anyOf2")) + .addAllOf(createSchema().ref("allOf1")) + .addAllOf(createSchema().ref("allOf2")) + .addOneOf(createSchema().ref("oneOf1")) + .addOneOf(createSchema().ref("oneOf2")) + .additionalPropertiesBoolean(true) + .items(createSchema().ref("items")) + .addExtension("x-ext", "ext-value") + ); } @Test @@ -145,4 +191,60 @@ public void discriminatorHasExpectedFields() { assertEquals("value1", mapping.get("key1").textValue()); assertEquals("value2", mapping.get("key2").textValue()); } + + @Test + public void schemaHasExpectedFields() { + JsonNode schema = path(getOpenAPIJson(), "components.schemas.Schema"); + assertNotNull(schema); + assertEquals("ext-value", schema.get("x-ext").textValue()); + assertEquals("title", schema.get("title").textValue()); + assertEquals(BigDecimal.ONE, schema.get("multipleOf").decimalValue()); + assertEquals(BigDecimal.ONE, schema.get("maximum").decimalValue()); + assertTrue(schema.get("exclusiveMaximum").booleanValue()); + assertEquals(BigDecimal.ONE, schema.get("minimum").decimalValue()); + assertTrue(schema.get("exclusiveMinimum").booleanValue()); + assertEquals(10, schema.get("maxLength").intValue()); + assertEquals(1, schema.get("minLength").intValue()); + assertEquals("pattern", schema.get("pattern").textValue()); + assertEquals(11, schema.get("maxItems").intValue()); + assertEquals(2, schema.get("minItems").intValue()); + assertTrue(schema.get("uniqueItems").booleanValue()); + assertEquals(12, schema.get("maxProperties").intValue()); + assertEquals(3, schema.get("minProperties").intValue()); + JsonNode required = schema.get("required"); + assertTrue(required.isArray()); + assertEquals(2, required.size()); + assertEquals("required1", required.get(0).textValue()); + assertEquals("required2", required.get(1).textValue()); + assertEquals("number", schema.get("type").textValue()); + assertTrue(schema.get("not").isObject()); + assertTrue(schema.get("properties").isObject()); + assertTrue(schema.get("properties").get("property1").isObject()); + assertEquals("description", schema.get("description").textValue()); + assertEquals("format", schema.get("format").textValue()); + assertTrue(schema.get("nullable").booleanValue()); + assertTrue(schema.get("readOnly").booleanValue()); + assertTrue(schema.get("writeOnly").booleanValue()); + assertEquals("example", schema.get("example").textValue()); + assertTrue(schema.get("externalDocs").isObject()); + assertTrue(schema.get("deprecated").booleanValue()); + assertTrue(schema.get("xml").isObject()); + JsonNode enumeration = schema.get("enum"); + assertTrue(enumeration.isArray()); + assertEquals(2, enumeration.size()); + assertEquals("enumeration1", enumeration.get(0).textValue()); + assertEquals("enumeration2", enumeration.get(1).textValue()); + assertTrue(schema.get("discriminator").isObject()); + JsonNode anyOf = schema.get("anyOf"); + assertTrue(anyOf.isArray()); + assertEquals(2, anyOf.size()); + JsonNode allOf = schema.get("allOf"); + assertTrue(allOf.isArray()); + assertEquals(2, allOf.size()); + JsonNode oneOf = schema.get("oneOf"); + assertTrue(oneOf.isArray()); + assertEquals(2, oneOf.size()); + assertTrue(schema.get("additionalProperties").booleanValue()); + assertTrue(schema.get("items").isObject()); + } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java index 324295dab14..d330350b676 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java @@ -1,9 +1,12 @@ package fish.payara.microprofile.openapi.impl.model; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import java.util.List; import java.util.function.BiPredicate; import org.eclipse.microprofile.openapi.models.Components; @@ -33,6 +36,7 @@ import org.eclipse.microprofile.openapi.models.security.OAuthFlow; import org.eclipse.microprofile.openapi.models.security.OAuthFlows; import org.eclipse.microprofile.openapi.models.security.Scopes; +import org.eclipse.microprofile.openapi.models.security.SecurityRequirement; import org.eclipse.microprofile.openapi.models.security.SecurityScheme; import org.eclipse.microprofile.openapi.models.servers.Server; import org.eclipse.microprofile.openapi.models.servers.ServerVariable; @@ -60,6 +64,7 @@ import fish.payara.microprofile.openapi.impl.model.security.OAuthFlowImpl; import fish.payara.microprofile.openapi.impl.model.security.OAuthFlowsImpl; import fish.payara.microprofile.openapi.impl.model.security.ScopesImpl; +import fish.payara.microprofile.openapi.impl.model.security.SecurityRequirementImpl; import fish.payara.microprofile.openapi.impl.model.security.SecuritySchemeImpl; import fish.payara.microprofile.openapi.impl.model.servers.ServerImpl; import fish.payara.microprofile.openapi.impl.model.servers.ServerVariableImpl; @@ -139,6 +144,23 @@ public void ScopesAddScopeDoesAcceptNull() { assertTrue(scopes.hasScope("foo")); } + @Test + public void SecurityRequirementAddSchemePutsEmptyListForNullItem() { + SecurityRequirement requirement = new SecurityRequirementImpl(); + requirement.addScheme("keyOnly"); + requirement.addScheme("nullItem", (String) null); + requirement.addScheme("nullList", (List) null); + List keyOnly = requirement.getScheme("keyOnly"); + assertNotNull(keyOnly); + assertEquals(0, keyOnly.size()); + List nullItem = requirement.getScheme("nullItem"); + assertNotNull(nullItem); + assertEquals(0, nullItem.size()); + List nullList = requirement.getScheme("nullList"); + assertNotNull(nullList); + assertEquals(0, nullList.size()); + } + private static void assertAddIgnoresNull(T modelObject, HasAdd addMethod, BiPredicate containsMethod) { String key = "whatever"; T res = addMethod.add(modelObject, key, null); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java index 352b69a8cd8..e443041276e 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/resource/rule/ApplicationProcessedDocument.java @@ -75,9 +75,7 @@ public static OpenAPI createDocument(Class filter, Class } return document; } catch (Exception ex) { - ex.printStackTrace(); - fail("Failed to build document."); - return null; + throw new AssertionError("Failed to build document.", ex); } } From 23402d80f1c2e79353c1772bcc2f2d469db76bd8 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 26 Mar 2019 12:21:09 +0100 Subject: [PATCH 074/108] PAYARA-3466 added tests for the model tags package --- .../openapi/impl/model/TagsBuilderTest.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/TagsBuilderTest.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/TagsBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/TagsBuilderTest.java new file mode 100644 index 00000000000..42493a702e0 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/TagsBuilderTest.java @@ -0,0 +1,38 @@ +package fish.payara.microprofile.openapi.impl.model; + +import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; +import static org.eclipse.microprofile.openapi.OASFactory.createExternalDocumentation; +import static org.eclipse.microprofile.openapi.OASFactory.createTag; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +/** + * Checks the JSON rendering of {@link fish.payara.microprofile.openapi.impl.model.tags.*}. + */ +public class TagsBuilderTest extends OpenApiBuilderTest { + + @Override + protected void setupBaseDocument(OpenAPI document) { + document.addTag(createTag() + .name("name") + .description("description") + .externalDocs(createExternalDocumentation().url("url")) + .addExtension("x-ext", "ext-value")); + } + + @Test + public void tagHasExpectedFields() { + JsonNode tag = path(getOpenAPIJson(), "tags.0"); + assertNotNull(tag); + assertEquals("name", tag.get("name").textValue()); + assertEquals("description", tag.get("description").textValue()); + assertEquals("ext-value", tag.get("x-ext").textValue()); + assertTrue(tag.get("externalDocs").isObject()); + } +} From e8b6a7186b4c3c38b59066992c66ffb0562f1ef2 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 26 Mar 2019 12:32:06 +0100 Subject: [PATCH 075/108] PAYARA-3466 made model fields private --- .../impl/model/callbacks/CallbackImpl.java | 2 +- .../impl/model/examples/ExampleImpl.java | 10 +-- .../impl/model/headers/HeaderImpl.java | 22 +++--- .../openapi/impl/model/info/ContactImpl.java | 6 +- .../openapi/impl/model/info/InfoImpl.java | 12 +-- .../openapi/impl/model/info/LicenseImpl.java | 4 +- .../openapi/impl/model/links/LinkImpl.java | 14 ++-- .../impl/model/media/DiscriminatorImpl.java | 4 +- .../impl/model/media/EncodingImpl.java | 10 +-- .../impl/model/media/MediaTypeImpl.java | 8 +- .../openapi/impl/model/media/SchemaImpl.java | 78 +++++++++---------- .../openapi/impl/model/media/XMLImpl.java | 10 +-- .../impl/model/parameters/ParameterImpl.java | 30 +++---- .../model/parameters/RequestBodyImpl.java | 8 +- .../impl/model/responses/APIResponseImpl.java | 10 +-- .../impl/model/security/OAuthFlowImpl.java | 8 +- .../impl/model/security/OAuthFlowsImpl.java | 8 +- .../model/security/SecuritySchemeImpl.java | 20 ++--- .../impl/model/servers/ServerImpl.java | 6 +- .../model/servers/ServerVariableImpl.java | 4 +- .../openapi/impl/model/tags/TagImpl.java | 6 +- 21 files changed, 140 insertions(+), 140 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java index 3d7f5866f0c..7810faca1c8 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/callbacks/CallbackImpl.java @@ -61,7 +61,7 @@ public class CallbackImpl extends ExtensibleTreeMap implemen private static final long serialVersionUID = 5549098533131353142L; - protected String ref; + private String ref; public CallbackImpl() { super(); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/examples/ExampleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/examples/ExampleImpl.java index 9c9174ed90c..1013d61468c 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/examples/ExampleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/examples/ExampleImpl.java @@ -52,11 +52,11 @@ public class ExampleImpl extends ExtensibleImpl implements Example { - protected String summary; - protected String description; - protected Object value; - protected String externalValue; - protected String ref; + private String summary; + private String description; + private Object value; + private String externalValue; + private String ref; @Override public String getSummary() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java index 994291f1e22..af0b8bd9b3f 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/headers/HeaderImpl.java @@ -57,17 +57,17 @@ public class HeaderImpl extends ExtensibleImpl

    implements Header { - protected String ref; - protected String description; - protected Boolean required; - protected Boolean deprecated; - protected Boolean allowEmptyValue; - protected Style style; - protected Boolean explode; - protected Schema schema; - protected Map examples = new HashMap<>(); - protected Object example; - protected Content content; + private String ref; + private String description; + private Boolean required; + private Boolean deprecated; + private Boolean allowEmptyValue; + private Style style; + private Boolean explode; + private Schema schema; + private Map examples = new HashMap<>(); + private Object example; + private Content content; @Override public String getRef() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/ContactImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/ContactImpl.java index 34e004474b3..a3ce917436d 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/ContactImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/ContactImpl.java @@ -48,9 +48,9 @@ public class ContactImpl extends ExtensibleImpl implements Contact { - protected String name; - protected String url; - protected String email; + private String name; + private String url; + private String email; @Override public String getName() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/InfoImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/InfoImpl.java index fbc518115d5..75a03c678d8 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/InfoImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/InfoImpl.java @@ -50,12 +50,12 @@ public class InfoImpl extends ExtensibleImpl implements Info { - protected String title; - protected String description; - protected String termsOfService; - protected Contact contact; - protected License license; - protected String version; + private String title; + private String description; + private String termsOfService; + private Contact contact; + private License license; + private String version; @Override public String getTitle() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/LicenseImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/LicenseImpl.java index f0e12dea008..d4b4d23fddf 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/LicenseImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/info/LicenseImpl.java @@ -48,8 +48,8 @@ public class LicenseImpl extends ExtensibleImpl implements License { - protected String name; - protected String url; + private String name; + private String url; @Override public String getName() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java index 45dde646c0a..6e488f4b1fd 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/links/LinkImpl.java @@ -55,13 +55,13 @@ public class LinkImpl extends ExtensibleImpl implements Link { - protected String operationRef; - protected String operationId; - protected Map parameters = new HashMap<>(); - protected Object requestBody; - protected String description; - protected String ref; - protected Server server; + private String operationRef; + private String operationId; + private Map parameters = new HashMap<>(); + private Object requestBody; + private String description; + private String ref; + private Server server; @Override public Server getServer() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java index 614a0989d3b..fed13912595 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/DiscriminatorImpl.java @@ -46,8 +46,8 @@ public class DiscriminatorImpl implements Discriminator { - protected String propertyName; - protected Map mapping = new HashMap<>(); + private String propertyName; + private Map mapping = new HashMap<>(); @Override public String getPropertyName() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java index 4a146052f91..d9e460f9fdd 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/EncodingImpl.java @@ -54,11 +54,11 @@ public class EncodingImpl extends ExtensibleImpl implements Encoding { - protected String contentType; - protected Map headers = new HashMap<>(); - protected Style style; - protected Boolean explode; - protected Boolean allowReserved; + private String contentType; + private Map headers = new HashMap<>(); + private Style style; + private Boolean explode; + private Boolean allowReserved; @Override public String getContentType() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java index 2a980c9b8d5..85145d1b478 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/MediaTypeImpl.java @@ -51,10 +51,10 @@ public class MediaTypeImpl extends ExtensibleImpl implements MediaType { - protected Schema schema; - protected Map examples = new HashMap<>(); - protected Object example; - protected Map encoding = new HashMap<>(); + private Schema schema; + private Map examples = new HashMap<>(); + private Object example; + private Map encoding = new HashMap<>(); @Override public Schema getSchema() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java index b44c8e91c86..5f8e4e52a52 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java @@ -69,45 +69,45 @@ public class SchemaImpl extends ExtensibleImpl implements Schema { private static final Logger LOGGER = Logger.getLogger(SchemaImpl.class.getName()); - protected Object defaultValue; - - protected String title; - protected BigDecimal multipleOf; - protected BigDecimal maximum; - protected Boolean exclusiveMaximum; - protected BigDecimal minimum; - protected Boolean exclusiveMinimum; - protected Integer maxLength; - protected Integer minLength; - protected String pattern; - protected Integer maxItems; - protected Integer minItems; - protected Boolean uniqueItems; - protected Integer maxProperties; - protected Integer minProperties; - protected List required = new ArrayList<>(); - protected SchemaType type; - protected Schema not; - protected Map properties = new HashMap<>(); - protected String description; - protected String format; - protected String ref; - protected Boolean nullable; - protected Boolean readOnly; - protected Boolean writeOnly; - protected Object example; - protected ExternalDocumentation externalDocs; - protected Boolean deprecated; - protected XML xml; - protected List enumeration = new ArrayList<>(); - protected Discriminator discriminator; - - protected List anyOf = new ArrayList<>(); - protected List allOf = new ArrayList<>(); - protected List oneOf = new ArrayList<>(); - - protected Object additionalProperties; - protected Schema items; + private Object defaultValue; + + private String title; + private BigDecimal multipleOf; + private BigDecimal maximum; + private Boolean exclusiveMaximum; + private BigDecimal minimum; + private Boolean exclusiveMinimum; + private Integer maxLength; + private Integer minLength; + private String pattern; + private Integer maxItems; + private Integer minItems; + private Boolean uniqueItems; + private Integer maxProperties; + private Integer minProperties; + private List required = new ArrayList<>(); + private SchemaType type; + private Schema not; + private Map properties = new HashMap<>(); + private String description; + private String format; + private String ref; + private Boolean nullable; + private Boolean readOnly; + private Boolean writeOnly; + private Object example; + private ExternalDocumentation externalDocs; + private Boolean deprecated; + private XML xml; + private List enumeration = new ArrayList<>(); + private Discriminator discriminator; + + private List anyOf = new ArrayList<>(); + private List allOf = new ArrayList<>(); + private List oneOf = new ArrayList<>(); + + private Object additionalProperties; + private Schema items; @Override public Discriminator getDiscriminator() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/XMLImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/XMLImpl.java index f27a34ffbe3..00080600024 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/XMLImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/XMLImpl.java @@ -45,11 +45,11 @@ public class XMLImpl extends ExtensibleImpl implements XML { - protected String name; - protected String namespace; - protected String prefix; - protected Boolean attribute; - protected Boolean wrapped; + private String name; + private String namespace; + private String prefix; + private Boolean attribute; + private Boolean wrapped; @Override public String getName() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java index 7b36cfadbdb..e3a450fff06 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/ParameterImpl.java @@ -62,21 +62,21 @@ public class ParameterImpl extends ExtensibleImpl implements Parameter { - protected String name; - protected In in; - protected String description; - protected Boolean required; - protected Boolean deprecated; - protected Boolean allowEmptyValue; - protected String ref; - - protected Style style; - protected Boolean explode; - protected Boolean allowReserved; - protected Schema schema; - protected Map examples = new HashMap<>(); - protected Object example; - protected Content content; + private String name; + private In in; + private String description; + private Boolean required; + private Boolean deprecated; + private Boolean allowEmptyValue; + private String ref; + + private Style style; + private Boolean explode; + private Boolean allowReserved; + private Schema schema; + private Map examples = new HashMap<>(); + private Object example; + private Content content; @Override public String getName() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/RequestBodyImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/RequestBodyImpl.java index 73f0d7329a3..07017ae414f 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/RequestBodyImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/parameters/RequestBodyImpl.java @@ -54,10 +54,10 @@ public class RequestBodyImpl extends ExtensibleImpl implements RequestBody { - protected String description; - protected Content content = new ContentImpl(); - protected Boolean required; - protected String ref; + private String description; + private Content content = new ContentImpl(); + private Boolean required; + private String ref; @Override public String getDescription() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java index 0ede06cf529..2a31c3c7cb4 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/responses/APIResponseImpl.java @@ -59,11 +59,11 @@ public class APIResponseImpl extends ExtensibleImpl implements APIResponse { - protected String description; - protected Map headers = new HashMap<>(); - protected Content content = new ContentImpl(); - protected Map links = new HashMap<>(); - protected String ref; + private String description; + private Map headers = new HashMap<>(); + private Content content = new ContentImpl(); + private Map links = new HashMap<>(); + private String ref; @Override public String getDescription() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowImpl.java index e6ad4daa23c..2b9ecf8a832 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowImpl.java @@ -50,10 +50,10 @@ public class OAuthFlowImpl extends ExtensibleImpl implements OAuthFlow { - protected String authorizationUrl; - protected String tokenUrl; - protected String refreshUrl; - protected Scopes scopes; + private String authorizationUrl; + private String tokenUrl; + private String refreshUrl; + private Scopes scopes; @Override public String getAuthorizationUrl() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowsImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowsImpl.java index 330324c787b..8f1c8817244 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowsImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/OAuthFlowsImpl.java @@ -49,10 +49,10 @@ public class OAuthFlowsImpl extends ExtensibleImpl implements OAuthFlows { - protected OAuthFlow implicit; - protected OAuthFlow password; - protected OAuthFlow clientCredentials; - protected OAuthFlow authorizationCode; + private OAuthFlow implicit; + private OAuthFlow password; + private OAuthFlow clientCredentials; + private OAuthFlow authorizationCode; @Override public OAuthFlow getImplicit() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecuritySchemeImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecuritySchemeImpl.java index c8a39503dc2..adcece03d7e 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecuritySchemeImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/security/SecuritySchemeImpl.java @@ -52,16 +52,16 @@ public class SecuritySchemeImpl extends ExtensibleImpl implements SecurityScheme { - protected SecurityScheme.Type type; - protected String description; - protected String name; - protected String ref; - - protected SecurityScheme.In in; - protected String scheme; - protected String bearerFormat; - protected OAuthFlows flows; - protected String openIdConnectUrl; + private SecurityScheme.Type type; + private String description; + private String name; + private String ref; + + private SecurityScheme.In in; + private String scheme; + private String bearerFormat; + private OAuthFlows flows; + private String openIdConnectUrl; @Override public SecurityScheme.Type getType() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java index b3dc2e1b159..b3e53bf437e 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerImpl.java @@ -52,9 +52,9 @@ public class ServerImpl extends ExtensibleImpl implements Server { - protected String url; - protected String description; - protected Map variables; + private String url; + private String description; + private Map variables; @Override public String getUrl() { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java index 20f4c61c702..42dd696fef5 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/servers/ServerVariableImpl.java @@ -48,8 +48,8 @@ public class ServerVariableImpl extends ExtensibleImpl implements ServerVariable { - protected String description; - protected String defaultValue; + private String description; + private String defaultValue; protected List enumeration = new ArrayList<>(); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/tags/TagImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/tags/TagImpl.java index 8610c01f985..d161faabfec 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/tags/TagImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/tags/TagImpl.java @@ -53,9 +53,9 @@ public class TagImpl extends ExtensibleImpl implements Tag { - protected String name; - protected String description; - protected ExternalDocumentation externalDocs; + private String name; + private String description; + private ExternalDocumentation externalDocs; @Override public String getName() { From bb87fa8cc4ba83d522c24e6fef70692916ebde5b Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 26 Mar 2019 13:13:02 +0100 Subject: [PATCH 076/108] PAYARA-3466 added tests for model references --- .../impl/model/ReferencesBuilderTest.java | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ReferencesBuilderTest.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ReferencesBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ReferencesBuilderTest.java new file mode 100644 index 00000000000..a04456c858c --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ReferencesBuilderTest.java @@ -0,0 +1,123 @@ +package fish.payara.microprofile.openapi.impl.model; + +import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; +import static org.eclipse.microprofile.openapi.OASFactory.createAPIResponse; +import static org.eclipse.microprofile.openapi.OASFactory.createCallback; +import static org.eclipse.microprofile.openapi.OASFactory.createExample; +import static org.eclipse.microprofile.openapi.OASFactory.createHeader; +import static org.eclipse.microprofile.openapi.OASFactory.createLink; +import static org.eclipse.microprofile.openapi.OASFactory.createParameter; +import static org.eclipse.microprofile.openapi.OASFactory.createPathItem; +import static org.eclipse.microprofile.openapi.OASFactory.createRequestBody; +import static org.eclipse.microprofile.openapi.OASFactory.createSchema; +import static org.eclipse.microprofile.openapi.OASFactory.createSecurityScheme; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.eclipse.microprofile.openapi.models.Components; +import org.eclipse.microprofile.openapi.models.OpenAPI; +import org.eclipse.microprofile.openapi.models.Reference; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +/** + * Checks the JSON rendering of all types that can be used as {@link Reference}. + */ +public class ReferencesBuilderTest extends OpenApiBuilderTest { + + private final String url = "http://example.com/"; + + @Override + protected void setupBaseDocument(OpenAPI document) { + String name = "NameRef"; + Components components = document.getComponents(); + components.addCallback("callbackRef", createCallback().ref(name)); + components.addCallback("callbackUrlRef", createCallback().ref(url)); + components.addExample("exampleRef", createExample().ref(name)); + components.addExample("exampleUrlRef", createExample().ref(url)); + components.addHeader("headerRef", createHeader().ref(name)); + components.addHeader("headerUrlRef", createHeader().ref(url)); + components.addResponse("responseRef", createAPIResponse().ref(name)); + components.addResponse("responseUrlRef", createAPIResponse().ref(url)); + components.addLink("linkRef", createLink().ref(name)); + components.addLink("linkUrlRef", createLink().ref(url)); + components.addParameter("parameterRef", createParameter().ref(name)); + components.addParameter("parameterUrlRef", createParameter().ref(url)); + components.addRequestBody("requestBodyRef", createRequestBody().ref(name)); + components.addRequestBody("requestBodyUrlRef", createRequestBody().ref(url)); + components.addSchema("schemaRef", createSchema().ref(name)); + components.addSchema("schemaUrlRef", createSchema().ref(url)); + components.addSecurityScheme("securitySchemeRef", createSecurityScheme().ref(name)); + components.addSecurityScheme("securitySchemeUrlRef", createSecurityScheme().ref(url)); + document.getPaths().addPathItem("pathItemRef", createPathItem().ref(name)); + document.getPaths().addPathItem("pathItemUrlRef", createPathItem().ref(url)); + } + + @Test + public void callbackReferenceHasExpectedFields() { + assertReference("#/components/callbacks/NameRef", "components.callbacks.callbackRef"); + assertReference(url, "components.callbacks.callbackUrlRef"); + } + + @Test + public void exampleReferenceHasExpectedFields() { + assertReference("#/components/examples/NameRef", "components.examples.exampleRef"); + assertReference(url, "components.examples.exampleUrlRef"); + } + + @Test + public void headerReferenceHasExpectedFields() { + assertReference("#/components/headers/NameRef", "components.headers.headerRef"); + assertReference(url, "components.headers.headerUrlRef"); + } + + @Test + public void responseReferenceHasExpectedFields() { + assertReference("#/components/responses/NameRef", "components.responses.responseRef"); + assertReference(url, "components.responses.responseUrlRef"); + } + + @Test + public void linkReferenceHasExpectedFields() { + assertReference("#/components/links/NameRef", "components.links.linkRef"); + assertReference(url, "components.links.linkUrlRef"); + } + + @Test + public void parameterReferenceHasExpectedFields() { + assertReference("#/components/parameters/NameRef", "components.parameters.parameterRef"); + assertReference(url, "components.parameters.parameterUrlRef"); + } + + @Test + public void requestBodyReferenceHasExpectedFields() { + assertReference("#/components/requestBodies/NameRef", "components.requestBodies.requestBodyRef"); + assertReference(url, "components.requestBodies.requestBodyUrlRef"); + } + + @Test + public void schemaReferenceHasExpectedFields() { + assertReference("#/components/schemas/NameRef", "components.schemas.schemaRef"); + assertReference(url, "components.schemas.schemaUrlRef"); + } + + @Test + public void securitySchemeReferenceHasExpectedFields() { + assertReference("#/components/securitySchemes/NameRef", "components.securitySchemes.securitySchemeRef"); + assertReference(url, "components.securitySchemes.securitySchemeUrlRef"); + } + + @Test + public void pathItemReferenceHasExpectedFields() { + assertReference("NameRef", "paths.pathItemRef"); + assertReference(url, "paths.pathItemUrlRef"); + } + + private void assertReference(String expected, String actualPath) { + JsonNode actual = path(getOpenAPIJson(), actualPath); + assertNotNull(actual); + assertEquals("References should only have one field", 1, actual.size()); + assertEquals(expected, actual.get("$ref").textValue()); + } +} From a315fda430a86c8e2d885105caabdf030ac1fa83 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 26 Mar 2019 13:18:28 +0100 Subject: [PATCH 077/108] PAYARA-3466 added copyright header where missing --- .../impl/model/ExamplesBuilderTest.java | 39 +++++++++++++++++++ .../impl/model/HeadersBuilderTest.java | 39 +++++++++++++++++++ .../openapi/impl/model/InfoBuilderTest.java | 39 +++++++++++++++++++ .../openapi/impl/model/LinksBuilderTest.java | 39 +++++++++++++++++++ .../openapi/impl/model/MediaBuilderTest.java | 39 +++++++++++++++++++ .../impl/model/ModelInvariantsTest.java | 39 +++++++++++++++++++ .../impl/model/OpenApiBuilderTest.java | 39 +++++++++++++++++++ .../impl/model/OperationsBuilderTest.java | 39 +++++++++++++++++++ .../impl/model/ParametersBuilderTest.java | 39 +++++++++++++++++++ .../openapi/impl/model/PathsBuilderTest.java | 39 +++++++++++++++++++ .../impl/model/ReferencesBuilderTest.java | 39 +++++++++++++++++++ .../impl/model/ResponsesBuilderTest.java | 39 +++++++++++++++++++ .../impl/model/SecurityBuilderTest.java | 39 +++++++++++++++++++ .../impl/model/ServersBuilderTest.java | 39 +++++++++++++++++++ .../openapi/impl/model/TagsBuilderTest.java | 39 +++++++++++++++++++ .../microprofile/openapi/spec/Field.java | 39 +++++++++++++++++++ .../microprofile/openapi/spec/NodeType.java | 39 +++++++++++++++++++ .../openapi/spec/OpenApiValidator.java | 39 +++++++++++++++++++ .../openapi/spec/OpenApiValidatorTest.java | 39 +++++++++++++++++++ .../test/app/OpenApiApplicationTest.java | 39 +++++++++++++++++++ .../test/app/application/CallbacksTest.java | 39 +++++++++++++++++++ .../test/app/application/OASFilterTest.java | 39 +++++++++++++++++++ .../app/application/SchemaReferenceTest.java | 39 +++++++++++++++++++ .../openapi/test/util/JsonUtils.java | 39 +++++++++++++++++++ 24 files changed, 936 insertions(+) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ExamplesBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ExamplesBuilderTest.java index 960c9931b30..0ddc6ee3945 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ExamplesBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ExamplesBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/HeadersBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/HeadersBuilderTest.java index ea4f66161f0..136507fd5ee 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/HeadersBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/HeadersBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/InfoBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/InfoBuilderTest.java index ab3484da27b..a246b4c529c 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/InfoBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/InfoBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/LinksBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/LinksBuilderTest.java index bb6270b010a..ceb676e0d47 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/LinksBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/LinksBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java index 6af69a31db0..e3873244f6d 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/MediaBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java index d330350b676..e3e4ccb3551 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ModelInvariantsTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static org.junit.Assert.assertEquals; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OpenApiBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OpenApiBuilderTest.java index 66a9cf9f5db..9ed5810d9ef 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OpenApiBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OpenApiBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.toJson; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OperationsBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OperationsBuilderTest.java index c1bb2011aac..32018cf7a20 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OperationsBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/OperationsBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ParametersBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ParametersBuilderTest.java index f180b6b2c0c..3e16dff89cf 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ParametersBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ParametersBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/PathsBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/PathsBuilderTest.java index 278ddfe5f7b..c123dba805f 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/PathsBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/PathsBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ReferencesBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ReferencesBuilderTest.java index a04456c858c..e8c8b36cb39 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ReferencesBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ReferencesBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ResponsesBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ResponsesBuilderTest.java index 3a93b049cae..5913e79e116 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ResponsesBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ResponsesBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SecurityBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SecurityBuilderTest.java index d1f9b596b80..bc551a0ff81 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SecurityBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/SecurityBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ServersBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ServersBuilderTest.java index 1b956bd53c1..13da8a4ccd1 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ServersBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/ServersBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/TagsBuilderTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/TagsBuilderTest.java index 42493a702e0..6be6b06f589 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/TagsBuilderTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/TagsBuilderTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.impl.model; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java index 2c54768c32d..b30957724d8 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/Field.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.spec; import java.util.EnumSet; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java index c49e060497a..6ad17b8fca4 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/NodeType.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.spec; import java.util.Arrays; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenApiValidator.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenApiValidator.java index fe7813699b3..118a1652d05 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenApiValidator.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenApiValidator.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.spec; import static java.util.Arrays.asList; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenApiValidatorTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenApiValidatorTest.java index 4533b9821b5..bed301c9ae1 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenApiValidatorTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/spec/OpenApiValidatorTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.spec; import java.io.File; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenApiApplicationTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenApiApplicationTest.java index d4193b4a4e4..aff059619e6 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenApiApplicationTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenApiApplicationTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.test.app; import static fish.payara.microprofile.openapi.test.util.JsonUtils.toJson; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java index ee75bcf0818..3cc2a4af40b 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.test.app.application; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/OASFilterTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/OASFilterTest.java index a06d5c51ed7..73269d732c0 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/OASFilterTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/OASFilterTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.test.app.application; import static org.eclipse.microprofile.openapi.OASFactory.createObject; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaReferenceTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaReferenceTest.java index 6aefe2d4654..71d6b2f6073 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaReferenceTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaReferenceTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.test.app.application; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/util/JsonUtils.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/util/JsonUtils.java index b84fd008872..5f5320046c8 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/util/JsonUtils.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/util/JsonUtils.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.test.util; import static org.junit.Assert.fail; From df9220362268f235a4bcb2b331862b0051a57ddd Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Tue, 26 Mar 2019 18:30:43 +0100 Subject: [PATCH 078/108] PAYARA-3660: Supply Common Classloader as locator when CommonModelRegistry is unavailable --- .../v3/server/ApplicationLifecycle.java | 21 +++++- .../ClassloaderResourceLocatorAdapter.java | 72 +++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ClassloaderResourceLocatorAdapter.java diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java index 347a475a401..537591ff216 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java @@ -71,6 +71,8 @@ import org.glassfish.hk2.classmodel.reflect.Parser; import org.glassfish.hk2.classmodel.reflect.ParsingContext; import org.glassfish.hk2.classmodel.reflect.Types; +import org.glassfish.hk2.classmodel.reflect.util.CommonModelRegistry; +import org.glassfish.hk2.classmodel.reflect.util.ResourceLocator; import org.glassfish.internal.api.ClassLoaderHierarchy; import org.glassfish.internal.data.*; import org.glassfish.internal.deployment.ApplicationLifecycleInterceptor; @@ -144,6 +146,9 @@ public class ApplicationLifecycle implements Deployment, PostConstruct { @Inject ConfigSupport configSupport; + @Inject + CommonClassLoaderServiceImpl commonClassLoaderService; + @Inject PayaraExecutorService executorService; @@ -575,8 +580,13 @@ public Types getDeployableTypes(DeploymentContext context) throws IOException { } else { try { + ResourceLocator locator = determineLocator(); // scan the jar and store the result in the deployment context. - ParsingContext parsingContext = new ParsingContext.Builder().logger(context.getLogger()).executorService(executorService.getUnderlyingExecutorService()).build(); + ParsingContext.Builder parsingContextBuilder = new ParsingContext.Builder().logger(context.getLogger()) + .executorService(executorService.getUnderlyingExecutorService()); + // workaround bug in Builder + parsingContextBuilder.locator(locator); + ParsingContext parsingContext = parsingContextBuilder.build(); Parser parser = new Parser(parsingContext); ReadableArchiveScannerAdapter scannerAdapter = new ReadableArchiveScannerAdapter(parser, context.getSource()); parser.parse(scannerAdapter, null); @@ -604,6 +614,15 @@ public Types getDeployableTypes(DeploymentContext context) throws IOException { } } + private ResourceLocator determineLocator() { + if (CommonModelRegistry.getInstance().canLoadResources()) { + // common model registry will handle our external class dependencies + return null; + } else { + return new ClassloaderResourceLocatorAdapter(commonClassLoaderService.getCommonClassLoader()); + } + } + private void notifyLifecycleInterceptorsBefore(final ExtendedDeploymentContext.Phase phase, final ExtendedDeploymentContext dc) { for (ApplicationLifecycleInterceptor i : alcInterceptors) { diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ClassloaderResourceLocatorAdapter.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ClassloaderResourceLocatorAdapter.java new file mode 100644 index 00000000000..4414a312860 --- /dev/null +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ClassloaderResourceLocatorAdapter.java @@ -0,0 +1,72 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package com.sun.enterprise.v3.server; + +import org.glassfish.hk2.classmodel.reflect.util.ResourceLocator; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.stream.Stream; + +class ClassloaderResourceLocatorAdapter implements ResourceLocator { + private static String[] BLACKLIST = {"java/","com/sun"}; + + private ClassLoader delegate; + + ClassloaderResourceLocatorAdapter(ClassLoader delegate) { + this.delegate = delegate; + } + + @Override + public InputStream openResourceStream(String name) throws IOException { + return isAllowed(name) ? delegate.getResourceAsStream(name) : null; + } + + @Override + public URL getResource(String name) { + return isAllowed(name) ? delegate.getResource(name) : null; + } + + private static boolean isAllowed(String name) { + return Stream.of(BLACKLIST).noneMatch(p -> name.startsWith(p)); + } +} From c4e0777a59062ad28c545809acbb62a821fb37b7 Mon Sep 17 00:00:00 2001 From: Fabio Turizo Date: Tue, 26 Mar 2019 13:22:08 -0500 Subject: [PATCH 079/108] Implemented fixes for JLine Logging --- .../sun/enterprise/admin/cli/CLICommand.java | 18 +++++++++++++++++- .../enterprise/admin/cli/MultimodeCommand.java | 16 +--------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/CLICommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/CLICommand.java index 274dfe04552..c907cc0e4eb 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/CLICommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/CLICommand.java @@ -133,7 +133,10 @@ public abstract class CLICommand implements PostConstruct { }; private String manpageTokenValues[] = new String[manpageTokens.length]; - + static{ + checkToDisableJLineLogging(); + } + /** * The name of the command. * Initialized in the constructor. @@ -1388,4 +1391,17 @@ private static void file2Set(String file, Set set) { e.printStackTrace(); } } + + private static void checkToDisableJLineLogging(){ + if (Boolean.getBoolean("fish.payara.admin.command.jline.log.disable")) { + System.setProperty("jline.log.jul", "false"); + final OutputStream noOpOutputStream = new OutputStream() { + @Override + public void write(int b) throws IOException { + //NO-OP + } + }; + jline.internal.Log.setOutput(new PrintStream(noOpOutputStream)); + } + } } diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/MultimodeCommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/MultimodeCommand.java index a94e75a9911..fb1264aeeb0 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/MultimodeCommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/MultimodeCommand.java @@ -137,8 +137,7 @@ protected Collection usageOptions() { protected int executeCommand() throws CommandException, CommandValidationException { ConsoleReader reader = null; programOpts.setEcho(echo); // restore echo flag, saved in validate - try { - checkToDisableJLineLogging(); + try { if (file == null) { System.out.println(strings.get("multimodeIntro")); reader = new ConsoleReader(ASADMIN, System.in, System.out, null, encoding); @@ -185,19 +184,6 @@ public void write(byte[] b, int off, int len) throws IOException { } } } - - private static void checkToDisableJLineLogging(){ - if (Boolean.getBoolean("fish.payara.admin.command.jline.log.disable")) { - System.setProperty("jline.log.jul", "false"); - final OutputStream noOpOutputStream = new OutputStream() { - @Override - public void write(int b) throws IOException { - //NO-OP - } - }; - jline.internal.Log.setOutput(new PrintStream(noOpOutputStream)); - } - } private static void atomicReplace(ServiceLocator locator, ProgramOptions options) { DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class); From 0ec331573d0fe7c8c7aa5bb02ba8d600fe851bb2 Mon Sep 17 00:00:00 2001 From: Sven Diedrichsen Date: Wed, 27 Mar 2019 00:32:53 +0100 Subject: [PATCH 080/108] Fixing sonar blocker bugs with unclosed resources and potential NPE --- .../glassfish/appclient/client/acc/Util.java | 23 +-- .../appclient/client/jws/boot/JWSACCMain.java | 136 ++++++-------- .../org/glassfish/appclient/common/Util.java | 21 +-- .../naming/util/NamingUtilsImpl.java | 48 +++-- .../connectors/util/JarResourceExtractor.java | 54 ++---- .../payara/ejb/invoke/InvokeEJBServlet.java | 85 +++++---- .../store/adapter/file/FileBackingStore.java | 28 +-- .../metrics/writer/JsonWriter.java | 39 ++-- .../oauth2/OAuth2AuthenticationMechanism.java | 35 ++-- .../openid/OpenIdAuthenticationMechanism.java | 28 +-- .../rest/client/utils/MarshallingUtils.java | 3 +- .../admin/rest/client/utils/Util.java | 33 ++-- .../admin/rest/testing/Response.java | 13 +- .../internal/embedded/ScatteredArchive.java | 36 ++-- .../embeddable/archive/Assembler.java | 177 +++++++++--------- 15 files changed, 367 insertions(+), 392 deletions(-) diff --git a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/Util.java b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/Util.java index 34a22615e9a..c6acc1aa6dd 100644 --- a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/Util.java +++ b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/Util.java @@ -132,22 +132,15 @@ public static URI getURI(final File f) throws URISyntaxException { * @throws FileNotFoundException if the temp file cannot be opened for any reason */ public static File writeTextToTempFile(String content, String prefix, String suffix, boolean retainTempFiles) throws IOException, FileNotFoundException { - BufferedWriter wtr = null; - try { - File result = File.createTempFile(prefix, suffix); - if ( ! retainTempFiles) { - result.deleteOnExit(); - } - FileOutputStream fos = new FileOutputStream(result); - wtr = new BufferedWriter(new OutputStreamWriter(fos)); - wtr.write(content); - wtr.close(); - return result; - } finally { - if (wtr != null) { - wtr.close(); - } + File result = File.createTempFile(prefix, suffix); + if ( ! retainTempFiles) { + result.deleteOnExit(); + } + try (BufferedWriter writer = + new BufferedWriter(new OutputStreamWriter(new FileOutputStream(result)))) { + writer.write(content); } + return result; } /** diff --git a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/jws/boot/JWSACCMain.java b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/jws/boot/JWSACCMain.java index 0d8c905e157..7d62f3d17c2 100644 --- a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/jws/boot/JWSACCMain.java +++ b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/jws/boot/JWSACCMain.java @@ -40,27 +40,22 @@ package org.glassfish.appclient.client.jws.boot; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; +import org.glassfish.appclient.client.acc.AppClientContainer; +import org.glassfish.appclient.client.acc.JWSACCClassLoader; +import org.glassfish.appclient.common.Util; + +import javax.swing.*; +import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.net.URLClassLoader; import java.security.Policy; import java.text.MessageFormat; import java.util.ResourceBundle; import java.util.Vector; -import javax.swing.SwingUtilities; -import org.glassfish.appclient.client.acc.AppClientContainer; -import org.glassfish.appclient.common.Util; -import org.glassfish.appclient.client.acc.JWSACCClassLoader; /** *Alternate main class for ACC, used when launched by Java Web Start. @@ -79,79 +74,79 @@ * @author tjquinn */ public class JWSACCMain implements Runnable { - + // /** path to a class in one of the app server lib jars downloaded by Java Web Start */ // private static final String APPSERVER_LIB_CLASS_NAME = "com.sun.enterprise.server.ApplicationServer"; - + /** name of the permissions template */ private static final String PERMISSIONS_TEMPLATE_NAME = "jwsclient.policy"; - + /** placeholder used in the policy template to substitute dynamically-generated grant clauses */ private static final String GRANT_CLAUSES_PROPERTY_EXPR = "${grant.clauses}"; - + /** line separator */ private static final String lineSep = System.getProperty("line.separator"); - + /** the user-specified security policy template to use */ private static String jwsPolicyTemplateURL = null; - + /** unpublished command-line argument conveying jwsacc information */ private static final String JWSACC_ARGUMENT_PREFIX = "-jwsacc"; - + private static final String JWSACC_EXIT_AFTER_RETURN = "ExitAfterReturn"; - + private static final String JWSACC_FORCE_ERROR = "ForceError"; - + private static final String JWSACC_KEEP_JWS_CLASS_LOADER = "KeepJWSClassLoader"; - + private static final String JWSACC_RUN_ON_SWING_THREAD = "RunOnSwingThread"; - + /** grant clause template for dynamically populating the policy */ private static final String GRANT_CLAUSE_TEMPLATE = "grant codeBase \"{0}\" '{'\n" + - " permission java.security.AllPermission;\n" + + " permission java.security.AllPermission;\n" + "'}';"; - + /** * request to exit the JVM upon return from the client - should be set (via - * the -jwsacc command-line argument value) only for + * the -jwsacc command-line argument value) only for * command-line clients; otherwise it can prematurely end the JVM when * the GUI and other user work is continuing */ private static boolean exitAfterReturn = false; - + /* *Normally the ACC is not run with the Java Web Start classloader as the *parent class loader because this causes problems loading dynamic stubs. - *To profile performance, though, sometimes we need to keep the JWS + *To profile performance, though, sometimes we need to keep the JWS *class loader as the parent rather than skipping it. */ private static boolean keepJWSClassLoader = false; - + private static boolean runOnSwingThread = false; - + /** helper for building the class loader and policy changes */ private static ClassPathManager classPathManager = null; - + /** URLs for downloaded JAR files to be used in the class path */ private static URL [] downloadedJarURLs; - + /** URLs for persistence-related JAR files for the class path and permissions */ private static URL [] persistenceJarURLs; - + /** localizable strings */ - private static final ResourceBundle rb = + private static final ResourceBundle rb = ResourceBundle.getBundle( dotToSlash(JWSACCMain.class.getPackage().getName() + ".LocalStrings")); /** make the arguments passed to the constructor available to the main method */ private String args[]; - + /** Creates a new instance of JWSMain */ public JWSACCMain(String[] args) { this.args = args; } - + /** * @param args the command line arguments */ @@ -162,7 +157,7 @@ public static void main(String[] args) { classPathManager = getClassPathManager(); downloadedJarURLs = classPathManager.locateDownloadedJars(); persistenceJarURLs = classPathManager.locatePersistenceJARs(); - + } catch (Throwable thr) { throw new IllegalArgumentException(rb.getString("jwsacc.errorLocJARs"), thr); } @@ -192,7 +187,7 @@ public static void main(String[] args) { System.exit(1); } } - + private static String dotToSlash(String orig) { return orig.replaceAll("\\.","/"); } @@ -234,7 +229,7 @@ public void run() { ErrorDisplayDialog.showErrors(thr, rb); } finally { /* - *If the user has requested, invoke System.exit as soon as the main + *If the user has requested, invoke System.exit as soon as the main *method returns. Do so on the Swing event thread so the ACC *main can complete whatever it may be doing. */ @@ -245,7 +240,7 @@ public void run() { System.out.printf("Exiting after return from client with status %1$d%n", statusValue); System.exit(statusValue); } - + public Runnable init(int exitStatus) { statusValue = exitStatus; return this; @@ -260,7 +255,7 @@ public Runnable init(int exitStatus) { } } } - + /** *Process any command line arguments that are targeted for the *Java Web Start ACC main program (this class) as opposed to the @@ -278,11 +273,11 @@ private static String[] prepareJWSArgs(String[] args) { nonJWSACCArgs.add(arg); } } - + processJWSArgs(JWSACCArgs); return nonJWSACCArgs.toArray(new String[nonJWSACCArgs.size()]); } - + /** *Interpret the JWSACC arguments (if any) supplied on the command line. *@param args the JWSACC arguments @@ -300,16 +295,16 @@ private static void processJWSArgs(Vector args) { } } } - + private static void setPermissions() { try { /* *Get the permissions template and write it to a temporary file. */ String permissionsTemplate = Util.loadResource(JWSACCMain.class, PERMISSIONS_TEMPLATE_NAME); - + /* - *Prepare the grant clauses for the downloaded jars and substitute + *Prepare the grant clauses for the downloaded jars and substitute *those clauses into the policy template. */ StringBuilder grantClauses = new StringBuilder(); @@ -317,17 +312,17 @@ private static void setPermissions() { for (URL url : downloadedJarURLs) { grantClauses.append(MessageFormat.format(GRANT_CLAUSE_TEMPLATE, url.toExternalForm())); } - + for (URL url : persistenceJarURLs) { grantClauses.append(MessageFormat.format(GRANT_CLAUSE_TEMPLATE, url.toExternalForm())); } - + String substitutedPermissionsTemplate = permissionsTemplate.replace(GRANT_CLAUSES_PROPERTY_EXPR, grantClauses.toString()); boolean retainTempFiles = Boolean.getBoolean(AppClientContainer.APPCLIENT_RETAIN_TEMP_FILES_PROPERTYNAME); File policyFile = writeTextToTempFile(substitutedPermissionsTemplate, "jwsacc", ".policy", retainTempFiles); refreshPolicy(policyFile); - + } catch (IOException ioe) { throw new RuntimeException("Error loading permissions template", ioe); } @@ -343,14 +338,14 @@ public static int firstFreePolicyIndex() { do { propValue = java.security.Security.getProperty("policy.url." + String.valueOf(++i)); } while ((propValue != null) && ( ! propValue.equals(""))); - + return i; } - + /** *Refreshes the current policy object using the contents of the specified file *as additional policy. - *@param policyFile the file containing additional policy + *@param policyFile the file containing additional policy */ public static void refreshPolicy(File policyFile) { int idx = firstFreePolicyIndex(); @@ -359,7 +354,7 @@ public static void refreshPolicy(File policyFile) { Policy p = Policy.getPolicy(); p.refresh(); } - + /** *The methods below are duplicates from the com.sun.enterprise.appclient.jws.Util class. *At the time this class is running, Java Web Start will not yet permit the Util class to @@ -378,48 +373,41 @@ public static void refreshPolicy(File policyFile) { *@throws FileNotFoundException if the temp file cannot be opened for any reason */ private static File writeTextToTempFile(String content, String prefix, String suffix, boolean retainTempFiles) throws IOException, FileNotFoundException { - BufferedWriter wtr = null; - try { - File result = File.createTempFile(prefix, suffix); - if ( ! retainTempFiles) { - result.deleteOnExit(); - } - FileOutputStream fos = new FileOutputStream(result); - wtr = new BufferedWriter(new OutputStreamWriter(fos)); + File result = File.createTempFile(prefix, suffix); + if ( ! retainTempFiles) { + result.deleteOnExit(); + } + try (BufferedWriter wtr = + new BufferedWriter(new OutputStreamWriter(new FileOutputStream(result)))){ wtr.write(content); - wtr.close(); - return result; - } finally { - if (wtr != null) { - wtr.close(); - } } + return result; } - + /** *Create the class loader for loading code from the unsigned downloaded *app server jars. *

    *During a Java Web Start launch the ACC will be run under this class loader. - *Otherwise the JNLPClassLoader will load any stub classes that are + *Otherwise the JNLPClassLoader will load any stub classes that are *packaged at the top-level of the generated app client jar file. (It can *see them because it downloaded the gen'd app client jar, and therefore *includes the downloaded jar in its class path. This allows it to see the *classes at the top level of the jar but does not automatically let it see *classes in the jars nested within the gen'd app client jar. As a result, - *the JNLPClassLoader would be the one to try to define the class for a + *the JNLPClassLoader would be the one to try to define the class for a *web services stub, for instance. But the loader will not be able to find - *other classes and interfaces needed to completely define the class - + *other classes and interfaces needed to completely define the class - *because these are in the jars nested inside the gen'd app client jar. So *the attempt to define the class would fail. *@param downloadedAppclientJarFile the app client jar file *@return the class loader */ private static ClassLoader prepareClassLoader(File downloadedAppclientJarFile) throws IOException, URISyntaxException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { - ClassLoader ldr = new JWSACCClassLoader(downloadedJarURLs, classPathManager.getParentClassLoader()); + ClassLoader ldr = new JWSACCClassLoader(downloadedJarURLs, classPathManager.getParentClassLoader()); return ldr; } - + /* *Returns the jar that contains the specified resource. *@param target entry name to look for @@ -437,7 +425,7 @@ private static File findContainingJar(String target, ClassLoader loader) throws } return result; } - + /** *Locate the app client jar file during a Java Web Start launch. *@param loader the class loader to use in searching for the descriptor entries @@ -461,7 +449,7 @@ private File findAppClientFileForJWSLaunch(ClassLoader loader) throws URISyntaxE } return containingJar; } - + /** *Return the class path manager appropriate to the current version. *@return the correct type of ClassPathManager diff --git a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/common/Util.java b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/common/Util.java index 655dad8bee7..6a6deb8238d 100644 --- a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/common/Util.java +++ b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/common/Util.java @@ -152,22 +152,15 @@ public static String getMainClassNameForAppClient(ModuleDescriptor moduleDescr) *@throws FileNotFoundException if the temp file cannot be opened for any reason */ public static File writeTextToTempFile(String content, String prefix, String suffix, boolean retainFile) throws IOException, FileNotFoundException { - BufferedWriter wtr = null; - try { - File result = File.createTempFile(prefix, suffix); - if ( ! retainFile) { - result.deleteOnExit(); - } - FileOutputStream fos = new FileOutputStream(result); - wtr = new BufferedWriter(new OutputStreamWriter(fos)); + File result = File.createTempFile(prefix, suffix); + if ( ! retainFile) { + result.deleteOnExit(); + } + try (BufferedWriter wtr = + new BufferedWriter(new OutputStreamWriter(new FileOutputStream(result)))) { wtr.write(content); - wtr.close(); - return result; - } finally { - if (wtr != null) { - wtr.close(); - } } + return result; } /** diff --git a/appserver/common/glassfish-naming/src/main/java/com/sun/enterprise/naming/util/NamingUtilsImpl.java b/appserver/common/glassfish-naming/src/main/java/com/sun/enterprise/naming/util/NamingUtilsImpl.java index 8a0aa778fa9..0dcc7e2e98e 100644 --- a/appserver/common/glassfish-naming/src/main/java/com/sun/enterprise/naming/util/NamingUtilsImpl.java +++ b/appserver/common/glassfish-naming/src/main/java/com/sun/enterprise/naming/util/NamingUtilsImpl.java @@ -44,13 +44,10 @@ import com.sun.enterprise.naming.spi.NamingObjectFactory; import com.sun.enterprise.naming.spi.NamingUtils; - import org.glassfish.logging.annotation.LogMessageInfo; - import org.jvnet.hk2.annotations.Service; import javax.inject.Singleton; - import javax.naming.Context; import java.io.*; import java.security.AccessController; @@ -58,7 +55,9 @@ import java.util.logging.Level; import static com.sun.enterprise.naming.util.LogFacade.logger; -import static org.glassfish.common.util.ObjectInputOutputStreamFactoryFactory.getFactory;; +import static org.glassfish.common.util.ObjectInputOutputStreamFactoryFactory.getFactory; + +; /** * This is a utils class for refactoring the following method. @@ -107,42 +106,41 @@ public NamingObjectFactory createDelegatingNamingObjectFactory(String name, NamingObjectFactory delegate, boolean cacheResult) { return new DelegatingNamingObjectFactory(name, delegate, cacheResult); } - + @Override public Object makeCopyOfObject(Object obj) { if ( !(obj instanceof Context) && (obj instanceof Serializable) ) { if(logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "** makeCopyOfObject:: " + obj); } - try { // first serialize the object - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = getFactory().createObjectOutputStream(bos); - oos.writeObject(obj); - oos.flush(); - byte[] data = bos.toByteArray(); - oos.close(); - bos.close(); - + byte[] data = serialize(obj); // now deserialize it - ByteArrayInputStream bis = new ByteArrayInputStream(data); - final ObjectInputStream ois = getFactory().createObjectInputStream(bis); - obj = AccessController.doPrivileged(new PrivilegedExceptionAction() { - @Override - public Object run() throws IOException, ClassNotFoundException { - return ois.readObject(); - } - }); - return obj; + return deserialize(data); } catch (Exception ex) { logger.log(Level.SEVERE, EXCEPTION_COPY_MUTABLE, ex); - RuntimeException re = new RuntimeException("Cant copy Serializable object:", ex); - throw re; + throw new RuntimeException("Cant copy Serializable object:", ex); } } else { // XXX no copy ? return obj; } } + + private Object deserialize(byte[] data) throws IOException, java.security.PrivilegedActionException { + try(final ObjectInputStream ois = + getFactory().createObjectInputStream(new ByteArrayInputStream(data))){ + return AccessController.doPrivileged((PrivilegedExceptionAction) () -> ois.readObject()); + } + } + + private byte[] serialize(Object obj) throws IOException { + try(ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = getFactory().createObjectOutputStream(bos)) { + oos.writeObject(obj); + oos.flush(); + return bos.toByteArray(); + } + } } diff --git a/appserver/connectors/connectors-runtime/src/main/java/com/sun/enterprise/connectors/util/JarResourceExtractor.java b/appserver/connectors/connectors-runtime/src/main/java/com/sun/enterprise/connectors/util/JarResourceExtractor.java index ff3eccc9116..02f4f1b3854 100644 --- a/appserver/connectors/connectors-runtime/src/main/java/com/sun/enterprise/connectors/util/JarResourceExtractor.java +++ b/appserver/connectors/connectors-runtime/src/main/java/com/sun/enterprise/connectors/util/JarResourceExtractor.java @@ -52,7 +52,7 @@ /** * JarResourceExtractor: JarResourceExtractor maps all resources included in a Zip or Jar file. * Additionaly, it provides a method to extract one as a blob. - * + * * @author Sivakumar Thyagarajan */ @@ -61,21 +61,21 @@ public final class JarResourceExtractor { //resourceName as String Vs contents as byte[] private Hashtable htJarContents = new Hashtable(); - + /** * creates a JarResourceExtractor. It extracts all resources from a Jar into an * internal hashtable, keyed by resource names. - * + * * @param jarFileName * a jar or zip file */ public JarResourceExtractor(String jarFileName) { init(jarFileName); } - + /** * Extracts a jar resource as a blob. - * + * * @param name * a resource name. */ @@ -85,33 +85,21 @@ public byte[] getResource(String name) { } return (byte[]) htJarContents.get(name); } - + /** initializes internal hash tables with Jar file resources. */ private void init(String jarFileName) { - ZipInputStream zis = null; - try { - //extract resources and put them into the hashtable. - FileInputStream fis = new FileInputStream(jarFileName); - BufferedInputStream bis = new BufferedInputStream(fis); - zis = new ZipInputStream(bis); + //extract resources and put them into the hashtable. + try (ZipInputStream zis = + new ZipInputStream(new BufferedInputStream(new FileInputStream(jarFileName)))) { extractResources(zis); } catch (Exception ex){ - ex.printStackTrace(); - }finally{ - if(zis != null){ - try{ - zis.close(); - }catch(Exception e){} + if(_logger.isLoggable(Level.WARNING)) { + _logger.log(Level.WARNING, "ExtractResources failed.", ex); } } - } - - /** - * @throws FileNotFoundException - * @throws IOException - */ - private void extractResources(ZipInputStream zis) throws FileNotFoundException, IOException { + + private void extractResources(ZipInputStream zis) throws IOException { ZipEntry ze = null; while ((ze = zis.getNextEntry()) != null) { if(_logger.isLoggable(Level.FINER)) { @@ -120,11 +108,7 @@ private void extractResources(ZipInputStream zis) throws FileNotFoundException, extractZipEntryContents(ze, zis); } } - - /** - * @param zis - * @throws IOException - */ + private void extractZipEntryContents(ZipEntry ze, ZipInputStream zis) throws IOException { if (ze.isDirectory()) { return; @@ -157,19 +141,19 @@ private void extractZipEntryContents(ZipEntry ze, ZipInputStream zis) throws IOE } } } - + private byte[] getZipEntryContents(ZipEntry ze, ZipInputStream zis) throws IOException{ int size = (int) ze.getSize(); - + byte[] b = null; // -1 means unknown size. if (size != -1) { //got a proper size, read 'size' bytes b = new byte[(int) size]; - + int rb = 0; int chunk = 0; - + while (((int) size - rb) > 0) { chunk = zis.read(b, rb, (int) size - rb); if (chunk == -1) { @@ -193,7 +177,7 @@ private byte[] getZipEntryContents(ZipEntry ze, ZipInputStream zis) throws IOExc b[i] = btArr[i].byteValue(); } } - + return b; } } diff --git a/appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java b/appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java index f0c16d2906e..fd0ee0ccd0b 100644 --- a/appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java +++ b/appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java @@ -45,14 +45,13 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import java.io.IOException; +import java.io.Reader; import java.util.Base64; import java.util.List; import java.util.function.Supplier; -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonString; -import javax.json.JsonValue; +import javax.json.*; +import javax.json.bind.Jsonb; import javax.json.bind.JsonbBuilder; import javax.naming.InitialContext; import javax.naming.NamingException; @@ -78,14 +77,12 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - - JsonObject requestPayload = - Json.createReader(request.getReader()) - .readObject(); - + + final JsonObject requestPayload = readJsonObject(request.getReader()); + if (request.getRequestURI().endsWith("lookup")) { boolean success = excuteInAppContext(() -> { - + try { response.getWriter().print( new InitialContext().lookup(requestPayload.getString("lookup")) @@ -96,69 +93,75 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) } catch (IOException | NamingException e) { // Ignore for now } - + return false; }); - + if (!success) { response.sendError(SC_INTERNAL_SERVER_ERROR, "Name " + requestPayload.getString("lookup") + " not found when doing initial lookup"); } - + return; } - + // Convert JSON encoded method parameter type names to actually Class instances - Class[] argTypes = + Class[] argTypes = requestPayload.getJsonArray("argTypes").stream() .map(e -> toClass(e)) .toArray(Class[]::new); - + // Convert JSON encoded method parameter values to their object instances List jsonArgValues = requestPayload.getJsonArray("argValues"); Object[] argValues = new Object[argTypes.length]; for (int i = 0; i < jsonArgValues.size(); i++) { argValues[i] = toObject(jsonArgValues.get(i), argTypes[i]); } - + boolean success = excuteInAppContext(() -> { try { // Obtain the target EJB that we're going to invoke Object bean = new InitialContext().lookup(requestPayload.getString("lookup")); - + // Authenticates the caller and if successful sets the security context // *for the outgoing EJB call*. In other words, the security context for this // Servlet will not be changed. if (requestPayload.containsKey(SECURITY_PRINCIPAL)) { ProgrammaticLogin login = new ProgrammaticLogin(); login.login( - base64Decode(requestPayload.getString(SECURITY_PRINCIPAL)), + base64Decode(requestPayload.getString(SECURITY_PRINCIPAL)), base64Decode(requestPayload.getString(SECURITY_CREDENTIALS)), null, true); } - + // Actually invoke the target EJB - Object result = + Object result = bean.getClass() .getMethod(requestPayload.getString("method"), argTypes) .invoke(bean, argValues); - + response.setContentType(APPLICATION_JSON); response.getWriter().print(result instanceof String? result : JsonbBuilder.create().toJson(result)); - + return true; - + } catch (Exception e) { e.printStackTrace(); } - + return false; }); - + if (!success) { response.sendError(SC_INTERNAL_SERVER_ERROR, "Name " + requestPayload.getString("lookup") + " not found when invoking"); } } - + + private JsonObject readJsonObject(Reader reader) { + try (JsonReader jsonReader = Json.createReader(reader)) { + return jsonReader.readObject(); + } + } + private Class toClass(JsonValue classNameValue) { try { String className = null; @@ -167,28 +170,30 @@ private Class toClass(JsonValue classNameValue) { } else { className = classNameValue.toString().replace("\"", ""); } - return Class.forName(className); } catch (ClassNotFoundException e) { throw new IllegalStateException(e); } } - + private Object toObject(JsonValue objectValue, Class type) { - return JsonbBuilder - .create() - .fromJson(objectValue.toString(), type); + try(Jsonb jsonb = JsonbBuilder.create()) { + return jsonb.fromJson(objectValue.toString(), type); + } catch (Exception e) { + // cannot really happen. It is just from java.lang.AutoCloseable interface + throw new IllegalStateException("Problem closing Jsonb.", e); + } } - + private boolean excuteInAppContext(Supplier body) { ApplicationRegistry registry = Globals.get(ApplicationRegistry.class); - + for (String applicationName : registry.getAllApplicationNames()) { ClassLoader existingContextClassLoader = Thread.currentThread().getContextClassLoader(); try { - + Thread.currentThread().setContextClassLoader(registry.get(applicationName).getAppClassLoader()); - + try { if (body.get()) { return true; @@ -196,18 +201,18 @@ private boolean excuteInAppContext(Supplier body) { } catch (Exception e) { // ignore } - + } finally { if (existingContextClassLoader != null) { Thread.currentThread().setContextClassLoader(existingContextClassLoader); } } - + } - + return false; } - + private static String base64Decode(String input) { return new String(Base64.getDecoder().decode(input)); } diff --git a/appserver/ha/ha-file-store/src/main/java/org/glassfish/ha/store/adapter/file/FileBackingStore.java b/appserver/ha/ha-file-store/src/main/java/org/glassfish/ha/store/adapter/file/FileBackingStore.java index 6efc2714e72..ba2fd01e98e 100644 --- a/appserver/ha/ha-file-store/src/main/java/org/glassfish/ha/store/adapter/file/FileBackingStore.java +++ b/appserver/ha/ha-file-store/src/main/java/org/glassfish/ha/store/adapter/file/FileBackingStore.java @@ -40,12 +40,15 @@ package org.glassfish.ha.store.adapter.file; -import org.glassfish.ha.store.api.*; +import org.glassfish.ha.store.api.BackingStore; +import org.glassfish.ha.store.api.BackingStoreConfiguration; +import org.glassfish.ha.store.api.BackingStoreException; +import org.glassfish.ha.store.api.BackingStoreFactory; import java.io.*; - import java.util.Map; -import java.util.logging.*; +import java.util.logging.Level; +import java.util.logging.Logger; /** * An implementation of BackingStore that uses file system to @@ -84,10 +87,10 @@ protected void initialize(BackingStoreConfiguration conf) if (conf.getLogger() != null) { logger = conf.getLogger(); } - + super.initialize(conf); debugStr = "[FileBackingStore - " + conf.getStoreName() + "] "; - + baseDir = conf.getBaseDirectory(); try { @@ -122,20 +125,17 @@ public BackingStoreFactory getBackingStoreFactory() { public V load(K key, String version) throws BackingStoreException { String fileName = key.toString(); - V value = null; - if (logger.isLoggable(TRACE_LEVEL)) { logger.log(TRACE_LEVEL, debugStr + "Entered load(" + key + ", " + version + ")"); } + V value = null; byte[] data = readFromfile(fileName); if (data != null) { - try { - ByteArrayInputStream bis2 = new ByteArrayInputStream(data); - ObjectInputStream ois = super.createObjectInputStream(bis2); + try (ObjectInputStream ois = + super.createObjectInputStream(new ByteArrayInputStream(data))) { value = (V) ois.readObject(); - if (logger.isLoggable(TRACE_LEVEL)) { logger.log(TRACE_LEVEL, debugStr + "Done load(" + key + ", " + version + ")"); } @@ -143,7 +143,7 @@ public V load(K key, String version) throws BackingStoreException { logger.log(Level.WARNING,debugStr + "Failed to load(" + key + ", " + version + ")", ex); } } - + return value; } @@ -198,7 +198,7 @@ public int removeExpired() { return removeExpired(defaultMaxIdleTimeoutInSeconds * 1000L); } - //TODO: deprecate after next shoal integration + //TODO: deprecate after next shoal integration public int removeExpired(long idleForMillis) { long threshold = System.currentTimeMillis() - idleForMillis; int expiredSessions = 0; @@ -271,7 +271,7 @@ public void updateTimeStamp(K k, String version, long timeStamp) throws BackingStoreException { updateTimestamp(k, timeStamp); } - + public void updateTimestamp(K sessionKey, long time) throws BackingStoreException { if (logger.isLoggable(TRACE_LEVEL)) { diff --git a/appserver/payara-appserver-modules/microprofile/metrics/src/main/java/fish/payara/microprofile/metrics/writer/JsonWriter.java b/appserver/payara-appserver-modules/microprofile/metrics/src/main/java/fish/payara/microprofile/metrics/writer/JsonWriter.java index dabbc0159f1..1ee30ad68c8 100644 --- a/appserver/payara-appserver-modules/microprofile/metrics/src/main/java/fish/payara/microprofile/metrics/writer/JsonWriter.java +++ b/appserver/payara-appserver-modules/microprofile/metrics/src/main/java/fish/payara/microprofile/metrics/writer/JsonWriter.java @@ -1,8 +1,8 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * + * * Copyright (c) [2018] Payara Foundation and/or its affiliates. All rights reserved. - * + * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You @@ -11,20 +11,20 @@ * https://github.com/payara/Payara/blob/master/LICENSE.txt * See the License for the specific * language governing permissions and limitations under the License. - * + * * When distributing the software, include this License Header Notice in each * file and include the License file at glassfish/legal/LICENSE.txt. - * + * * GPL Classpath Exception: * The Payara Foundation designates this particular file as subject to the "Classpath" * exception as provided by the Payara Foundation in the GPL Version 2 section of the License * file that accompanied this code. - * + * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" - * + * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] @@ -43,24 +43,23 @@ import fish.payara.microprofile.metrics.MetricsService; import fish.payara.microprofile.metrics.exception.NoSuchMetricException; import fish.payara.microprofile.metrics.exception.NoSuchRegistryException; +import org.glassfish.internal.api.Globals; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; import java.io.IOException; import java.io.Writer; import java.util.Map; import java.util.logging.Logger; + import static java.util.stream.Collectors.joining; -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonObjectBuilder; -import javax.json.JsonWriterFactory; -import static org.eclipse.microprofile.metrics.MetricRegistry.Type.APPLICATION; -import static org.eclipse.microprofile.metrics.MetricRegistry.Type.BASE; -import static org.eclipse.microprofile.metrics.MetricRegistry.Type.VENDOR; -import org.glassfish.internal.api.Globals; +import static org.eclipse.microprofile.metrics.MetricRegistry.Type.*; public abstract class JsonWriter implements MetricsWriter { private final Writer writer; - + protected final MetricsService service; protected static final Logger LOGGER = Logger.getLogger(JsonWriter.class.getName()); @@ -133,18 +132,20 @@ public void write() throws IOException { } protected void serialize(JsonObject payload) throws IOException { - JsonWriterFactory jsonWriterFactory = Json.createWriterFactory(null); - jsonWriterFactory.createWriter(writer).writeObject(payload); + try (javax.json.JsonWriter jsonWriter = + Json.createWriterFactory(null).createWriter(writer)) { + jsonWriter.writeObject(payload); + } } protected JsonObject getJsonFromMap(Map map) { JsonObjectBuilder payloadBuilder = Json.createObjectBuilder(); for (Map.Entry entry : map.entrySet()) { - addValueToJsonObject(payloadBuilder, entry.getKey(), entry.getValue()); + addValueToJsonObject(payloadBuilder, entry.getKey(), entry.getValue()); } return payloadBuilder.build(); } - + protected void addValueToJsonObject(JsonObjectBuilder payloadBuilder, String key, Number value){ if (value instanceof Integer) { payloadBuilder.add(key, value.intValue()); diff --git a/appserver/payara-appserver-modules/security-oauth2/src/main/java/fish/payara/security/oauth2/OAuth2AuthenticationMechanism.java b/appserver/payara-appserver-modules/security-oauth2/src/main/java/fish/payara/security/oauth2/OAuth2AuthenticationMechanism.java index 0748db199b3..b9c443b12fd 100644 --- a/appserver/payara-appserver-modules/security-oauth2/src/main/java/fish/payara/security/oauth2/OAuth2AuthenticationMechanism.java +++ b/appserver/payara-appserver-modules/security-oauth2/src/main/java/fish/payara/security/oauth2/OAuth2AuthenticationMechanism.java @@ -1,8 +1,8 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * + * * Copyright (c) [2018] Payara Foundation and/or its affiliates. All rights reserved. - * + * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You @@ -11,20 +11,20 @@ * https://github.com/payara/Payara/blob/master/LICENSE.txt * See the License for the specific * language governing permissions and limitations under the License. - * + * * When distributing the software, include this License Header Notice in each * file and include the License file at glassfish/legal/LICENSE.txt. - * + * * GPL Classpath Exception: * The Payara Foundation designates this particular file as subject to the "Classpath" * exception as provided by the Payara Foundation in the GPL Version 2 section of the License * file that accompanied this code. - * + * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" - * + * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] @@ -48,6 +48,7 @@ import javax.json.Json; import javax.json.JsonObject; +import javax.json.JsonReader; import javax.security.enterprise.AuthenticationException; import javax.security.enterprise.AuthenticationStatus; import javax.security.enterprise.authentication.mechanism.http.AutoApplySession; @@ -86,7 +87,7 @@ public class OAuth2AuthenticationMechanism implements HttpAuthenticationMechanism { private static final Logger logger = Logger.getLogger("OAuth2Mechanism"); - + private final ELProcessor elProcessor; private String authEndpoint; @@ -105,7 +106,7 @@ public class OAuth2AuthenticationMechanism implements HttpAuthenticationMechanis @Inject private IdentityStoreHandler identityStoreHandler; - + /** * Creates an OAuth2AuthenticationMechanism. *

    @@ -143,7 +144,7 @@ public OAuth2AuthenticationMechanism setDefinition(OAuth2AuthenticationDefinitio clientSecret = getConfiguredValue(definition.clientSecret(), provider, OAuth2AuthenticationDefinition.OAUTH2_MP_CLIENT_SECRET).toCharArray(); redirectURI = getConfiguredValue(definition.redirectURI(), provider, OAuth2AuthenticationDefinition.OAUTH2_MP_REDIRECT_URI); scopes = getConfiguredValue(definition.scope(), provider, OAuth2AuthenticationDefinition.OAUTH2_MP_SCOPE); - + String[] params = definition.extraParameters(); extraParameters = new String[params.length]; for (int i = 0; i < params.length; i++) { @@ -215,7 +216,7 @@ private AuthenticationStatus validateCallback(HttpServletRequest request, HttpMe // Get back the result of the REST request String result = oauthResponse.readEntity(String.class); - JsonObject object = Json.createReader(new StringReader(result)).readObject(); + JsonObject object = readJsonObject(result); logger.log(Level.FINEST, "Response code from endpoint: {0}", oauthResponse.getStatus()); if (oauthResponse.getStatus() != 200) { @@ -239,6 +240,12 @@ private AuthenticationStatus validateCallback(HttpServletRequest request, HttpMe } } + private JsonObject readJsonObject(String result) { + try (JsonReader reader = Json.createReader(new StringReader(result))) { + return reader.readObject(); + } + } + /** * If the user is not logged in then redirect them to OAuth provider * @@ -264,7 +271,7 @@ private AuthenticationStatus redirectForAuth(HttpMessageContext context) { return context.redirect(authTokenRequest.toString()); } - + private String getConfiguredValue(String value, Config provider, String mpConfigKey){ String result = value; Optional configResult = provider.getOptionalValue(mpConfigKey, String.class); @@ -275,14 +282,14 @@ private String getConfiguredValue(String value, Config provider, String mpConfig if (isELExpression(value)){ result = (String) elProcessor.getValue(toRawExpression(result), String.class); } - + return result; } - + private static boolean isELExpression(String expression) { return !expression.isEmpty() && isDeferredExpression(expression); } - + private static boolean isDeferredExpression(String expression) { return expression.startsWith("#{") && expression.endsWith("}"); } diff --git a/appserver/payara-appserver-modules/security-openid/src/main/java/fish/payara/security/openid/OpenIdAuthenticationMechanism.java b/appserver/payara-appserver-modules/security-openid/src/main/java/fish/payara/security/openid/OpenIdAuthenticationMechanism.java index ca5879e459b..7b26296aad6 100644 --- a/appserver/payara-appserver-modules/security-openid/src/main/java/fish/payara/security/openid/OpenIdAuthenticationMechanism.java +++ b/appserver/payara-appserver-modules/security-openid/src/main/java/fish/payara/security/openid/OpenIdAuthenticationMechanism.java @@ -1,8 +1,8 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * + * * Copyright (c) [2018] Payara Foundation and/or its affiliates. All rights reserved. - * + * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You @@ -11,20 +11,20 @@ * https://github.com/payara/Payara/blob/master/LICENSE.txt * See the License for the specific * language governing permissions and limitations under the License. - * + * * When distributing the software, include this License Header Notice in each * file and include the License file at glassfish/legal/LICENSE.txt. - * + * * GPL Classpath Exception: * The Payara Foundation designates this particular file as subject to the "Classpath" * exception as provided by the Payara Foundation in the GPL Version 2 section of the License * file that accompanied this code. - * + * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" - * + * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] @@ -63,6 +63,7 @@ import javax.inject.Inject; import javax.json.Json; import javax.json.JsonObject; +import javax.json.JsonReader; import javax.security.enterprise.AuthenticationException; import javax.security.enterprise.AuthenticationStatus; import javax.security.enterprise.authentication.mechanism.http.AutoApplySession; @@ -209,9 +210,8 @@ public AuthenticationStatus validateRequest( * Authorization Code Flow must be validated and exchanged for an ID Token, * an Access Token and optionally a Refresh Token directly. * - * @param request - * @param context - * @return + * @param httpContext the {@link HttpMessageContext} to validate authorization code from + * @return the authentication status. */ private AuthenticationStatus validateAuthorizationCode(HttpMessageContext httpContext) { HttpServletRequest request = httpContext.getRequest(); @@ -227,9 +227,7 @@ private AuthenticationStatus validateAuthorizationCode(HttpMessageContext httpCo LOGGER.finer("Authorization Code received, now fetching Access token & Id token"); Response response = tokenController.getTokens(configuration, request); - String tokensBody = response.readEntity(String.class); - JsonObject tokensObject = Json.createReader(new StringReader(tokensBody)).readObject(); - + JsonObject tokensObject = readJsonObject(response.readEntity(String.class)); if (response.getStatus() == Status.OK.getStatusCode()) { // Successful Token Response updateContext(tokensObject, httpContext); @@ -245,6 +243,12 @@ private AuthenticationStatus validateAuthorizationCode(HttpMessageContext httpCo } } + private JsonObject readJsonObject(String tokensBody) { + try(JsonReader reader = Json.createReader(new StringReader(tokensBody))) { + return reader.readObject(); + } + } + private void updateContext(JsonObject tokensObject, HttpMessageContext httpContext) { context.setProviderMetadata(configuration.getProviderMetadata().getDocument()); context.setTokenType(tokensObject.getString(TOKEN_TYPE, null)); diff --git a/nucleus/admin/rest/rest-client/src/main/java/org/glassfish/admin/rest/client/utils/MarshallingUtils.java b/nucleus/admin/rest/rest-client/src/main/java/org/glassfish/admin/rest/client/utils/MarshallingUtils.java index e3fa53fd426..0736970a2ea 100644 --- a/nucleus/admin/rest/rest-client/src/main/java/org/glassfish/admin/rest/client/utils/MarshallingUtils.java +++ b/nucleus/admin/rest/rest-client/src/main/java/org/glassfish/admin/rest/client/utils/MarshallingUtils.java @@ -77,8 +77,7 @@ public static List> getPropertiesFromJson(String json) { properties = new ArrayList>(); properties.add(Util.processJsonMap(json)); } else if (json.startsWith("[")) { - try { - JsonParser parser = Json.createParser(new StringReader(json)); + try (JsonParser parser = Json.createParser(new StringReader(json))) { parser.next(); properties = Util.processJsonArray(parser.getArray()); } catch (JsonException e) { diff --git a/nucleus/admin/rest/rest-client/src/main/java/org/glassfish/admin/rest/client/utils/Util.java b/nucleus/admin/rest/rest-client/src/main/java/org/glassfish/admin/rest/client/utils/Util.java index f2474167a93..9db1506a552 100644 --- a/nucleus/admin/rest/rest-client/src/main/java/org/glassfish/admin/rest/client/utils/Util.java +++ b/nucleus/admin/rest/rest-client/src/main/java/org/glassfish/admin/rest/client/utils/Util.java @@ -3,10 +3,10 @@ * * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved. * - * The contents of this file are subject to the terms of either the GNU + * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific @@ -28,7 +28,7 @@ * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL + * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to @@ -36,7 +36,7 @@ * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. - * + * */ // Portions Copyright [2017-2018] Payara Foundation and/or affiliates @@ -65,7 +65,7 @@ * @see org.glassfish.admin.rest.utils.JsonUtil */ public class Util { - + /** * Converts a String of JSON data into a map * If there is an error then an empty Map will be returned. @@ -74,16 +74,15 @@ public class Util { */ public static Map processJsonMap(String json) { Map map; - try { - JsonParser parser = Json.createParser(new StringReader(json)); + try (JsonParser parser = Json.createParser(new StringReader(json))) { if (parser.hasNext()){ parser.next(); - map = processJsonObject(parser.getObject()); + map = processJsonObject(parser.getObject()); } else { - map = new HashMap(); + map = new HashMap<>(); } } catch (JsonException e) { - map = new HashMap(); + map = new HashMap<>(); } return map; } @@ -95,10 +94,10 @@ public static Map processJsonMap(String json) { * {@link Map}, {@link Number}, {@code null} and/or {@link String}. *

    * @param jsonObject - * @return + * @return */ - public static Map processJsonObject(JsonObject jsonObject) { - Map map = new HashMap(); + public static Map processJsonObject(JsonObject jsonObject) { + Map map = new HashMap<>(); try { for (String key : jsonObject.keySet()) { JsonValue value = jsonObject.get(key); @@ -120,7 +119,7 @@ public static Map processJsonObject(JsonObject jsonObject) { case TRUE: map.put(key, Boolean.TRUE); break; - case FALSE: + case FALSE: map.put(key, Boolean.FALSE); break; default: @@ -142,11 +141,11 @@ public static Map processJsonObject(JsonObject jsonObject) { * {@link Map}, {@link Number} and/or {@link String}. *

    * @param jsonArray - * @return + * @return */ public static List processJsonArray(JsonArray jsonArray) { List results = new ArrayList(); - + try { for (JsonValue entry: jsonArray) { if (null == entry.getValueType()) { diff --git a/nucleus/admin/rest/rest-testing/src/main/java/org/glassfish/admin/rest/testing/Response.java b/nucleus/admin/rest/rest-testing/src/main/java/org/glassfish/admin/rest/testing/Response.java index d76be5e8947..08bbe2c61df 100644 --- a/nucleus/admin/rest/rest-testing/src/main/java/org/glassfish/admin/rest/testing/Response.java +++ b/nucleus/admin/rest/rest-testing/src/main/java/org/glassfish/admin/rest/testing/Response.java @@ -87,12 +87,13 @@ public String getStringBody() { } public JsonObject getJsonBody() throws Exception { - JsonParser parser = Json.createParser(new StringReader(getStringBody())); - if (parser.hasNext()){ - parser.next(); - return parser.getObject(); - } else { - return JsonValue.EMPTY_JSON_OBJECT; + try (JsonParser parser = Json.createParser(new StringReader(getStringBody()))){ + if (parser.hasNext()){ + parser.next(); + return parser.getObject(); + } else { + return JsonValue.EMPTY_JSON_OBJECT; + } } } diff --git a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/embedded/ScatteredArchive.java b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/embedded/ScatteredArchive.java index 52d8b7a29c1..f43a3f66086 100644 --- a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/embedded/ScatteredArchive.java +++ b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/embedded/ScatteredArchive.java @@ -334,14 +334,15 @@ public Enumeration entries() { f = new File(url.getPath()); } if (f.isFile()) { - JarFile jar = new JarFile(f); - Enumeration jarEntries = jar.entries(); - while (jarEntries.hasMoreElements()) { - JarEntry jarEntry = jarEntries.nextElement(); - if (jarEntry.isDirectory()) { - continue; + try (JarFile jar = new JarFile(f)) { + Enumeration jarEntries = jar.entries(); + while (jarEntries.hasMoreElements()) { + JarEntry jarEntry = jarEntries.nextElement(); + if (jarEntry.isDirectory()) { + continue; + } + entries.add(jarEntry.getName()); } - entries.add(jarEntry.getName()); } } else { getListOfFiles(f, prefix, entries); @@ -360,12 +361,17 @@ public Enumeration entries() { private void getListOfFiles(File directory, String prefix, List list) { if (!directory.isDirectory()) return; - for (File f : directory.listFiles()) { - String name = prefix==null?f.getName():prefix+"/"+f.getName(); - if (f.isDirectory()) { - getListOfFiles(f, name ,list); - } else { - list.add(name); + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + String name = prefix == null + ? file.getName() + : prefix + "/" + file.getName(); + if (file.isDirectory()) { + getListOfFiles(file, name ,list); + } else { + list.add(name); + } } } } @@ -511,7 +517,7 @@ public File getFile(String name) { private JarFile getJarWithEntry(String name) { for (URL url : urls) { - File f = null; + File f; try { f = new File(url.toURI()); } catch(URISyntaxException e) { @@ -522,6 +528,8 @@ private JarFile getJarWithEntry(String name) { JarFile jar = new JarFile(f); if (jar.getEntry(name) != null) { return jar; + } else { + jar.close(); } } } catch (Exception ex) { diff --git a/nucleus/common/scattered-archive-api/src/main/java/org/glassfish/embeddable/archive/Assembler.java b/nucleus/common/scattered-archive-api/src/main/java/org/glassfish/embeddable/archive/Assembler.java index 0fbfb35adb2..3499525eab4 100644 --- a/nucleus/common/scattered-archive-api/src/main/java/org/glassfish/embeddable/archive/Assembler.java +++ b/nucleus/common/scattered-archive-api/src/main/java/org/glassfish/embeddable/archive/Assembler.java @@ -88,19 +88,19 @@ private URI assembleEAR(String name, Map archives, Map metadatas) throws IOException { File ear = new File(System.getProperty("java.io.tmpdir"), name + ".ear"); ear.deleteOnExit(); - JarOutputStream jos = new JarOutputStream(new FileOutputStream(ear)); - for (Map.Entry me : metadatas.entrySet()) { - tranferFile(me.getValue(), jos, me.getKey(), false); - } - for (Map.Entry ame : archives.entrySet()) { - File archive = ame.getValue(); - if (archive.isDirectory()) { - archive = new File(assembleJAR(ame.getKey(), archive, - Collections.EMPTY_LIST, Collections.EMPTY_MAP)); + try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(ear))) { + for (Map.Entry me : metadatas.entrySet()) { + tranferFile(me.getValue(), jos, me.getKey(), false); + } + for (Map.Entry ame : archives.entrySet()) { + File archive = ame.getValue(); + if (archive.isDirectory()) { + archive = new File(assembleJAR(ame.getKey(), archive, + Collections.emptyList(), Collections.emptyMap())); + } + tranferFile(archive, jos, ame.getKey(), false); } - tranferFile(archive, jos, ame.getKey(), false); } - jos.close(); return ear.toURI(); } @@ -110,20 +110,20 @@ URI assembleWAR(String name, File rootDirectory, List classpaths, File archive = new File(System.getProperty("java.io.tmpdir"), name + ".war"); archive.deleteOnExit(); - JarOutputStream jos = new JarOutputStream(new FileOutputStream(archive)); - - transferDir(rootDirectory, jos, ""); - for (Map.Entry me : metadatas.entrySet()) { - tranferFile(me.getValue(), jos, me.getKey(), false); - } - for (File classpath : classpaths) { - if (classpath.isDirectory()) { - transferDir(classpath, jos, "WEB-INF/classes/"); - } else { - tranferFile(classpath, jos, "WEB-INF/lib/" + classpath.getName(), false); + try(JarOutputStream jos = new JarOutputStream(new FileOutputStream(archive))) { + transferDir(rootDirectory, jos, ""); + for (Map.Entry me : metadatas.entrySet()) { + tranferFile(me.getValue(), jos, me.getKey(), false); + } + for (File classpath : classpaths) { + if (classpath.isDirectory()) { + transferDir(classpath, jos, "WEB-INF/classes/"); + } else { + tranferFile(classpath, jos, "WEB-INF/lib/" + classpath.getName(), false); + } } } - jos.close(); + return archive.toURI(); } @@ -131,19 +131,19 @@ URI assembleJAR(String name, File rootDirectory, List classpaths, Map metadatas) throws IOException { File archive = new File(System.getProperty("java.io.tmpdir"), name + ".jar"); archive.deleteOnExit(); - JarOutputStream jos = new JarOutputStream(new FileOutputStream(archive)); - transferDir(rootDirectory, jos, ""); - for (Map.Entry me : metadatas.entrySet()) { - tranferFile(me.getValue(), jos, me.getKey(), false); - } - for (File classpath : classpaths) { - if (classpath.isDirectory()) { - transferDir(classpath, jos, ""); - } else { - tranferFile(classpath, jos, "", true); + try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(archive))) { + transferDir(rootDirectory, jos, ""); + for (Map.Entry me : metadatas.entrySet()) { + tranferFile(me.getValue(), jos, me.getKey(), false); + } + for (File classpath : classpaths) { + if (classpath.isDirectory()) { + transferDir(classpath, jos, ""); + } else { + tranferFile(classpath, jos, "", true); + } } } - jos.close(); return archive.toURI(); } @@ -151,42 +151,41 @@ URI assembleRAR(String name, File rootDirectory, List classpaths, Map metadatas) throws IOException { File rar = new File(System.getProperty("java.io.tmpdir"), name + ".rar"); rar.deleteOnExit(); - JarOutputStream jos = new JarOutputStream(new FileOutputStream(rar)); - transferDir(rootDirectory, jos, ""); - for (Map.Entry me : metadatas.entrySet()) { - tranferFile(me.getValue(), jos, me.getKey(), false); - } - - // Make a single connector jar out of all the classpath directories and add it to the RAR file. - List classpathDirs = new ArrayList(); - for (File classpath : classpaths) { - if (classpath.isDirectory()) { - classpathDirs.add(classpath); + try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(rar))) { + transferDir(rootDirectory, jos, ""); + for (Map.Entry me : metadatas.entrySet()) { + tranferFile(me.getValue(), jos, me.getKey(), false); } - } - if (!classpathDirs.isEmpty()) { - // Compute a unique connector jar name - String connectorJarName = name; - List topLevelFileNames = new ArrayList(); - topLevelFileNames.addAll(getFileNames(classpaths)); - topLevelFileNames.addAll(getFileNames(rootDirectory)); - int count = 0; - while (topLevelFileNames.contains(connectorJarName + ".jar")) { - connectorJarName = name + "_" + count; - ++count; + // Make a single connector jar out of all the classpath directories and add it to the RAR file. + List classpathDirs = new ArrayList<>(); + for (File classpath : classpaths) { + if (classpath.isDirectory()) { + classpathDirs.add(classpath); + } + } + if (!classpathDirs.isEmpty()) { + // Compute a unique connector jar name + String connectorJarName = name; + List topLevelFileNames = new ArrayList<>(); + topLevelFileNames.addAll(getFileNames(classpaths)); + topLevelFileNames.addAll(getFileNames(rootDirectory)); + int count = 0; + while (topLevelFileNames.contains(connectorJarName + ".jar")) { + connectorJarName = name + "_" + count; + ++count; + } + File connectorJar = new File(assembleJAR(connectorJarName, null, + classpathDirs, Collections.emptyMap())); + tranferFile(connectorJar, jos, connectorJar.getName(), false); } - File connectorJar = new File(assembleJAR(connectorJarName, null, - classpathDirs, Collections.EMPTY_MAP)); - tranferFile(connectorJar, jos, connectorJar.getName(), false); - } - // Add all the classpath files to the RAR files. - for (File classpath : classpaths) { - if (!classpath.isDirectory()) { - tranferFile(classpath, jos, classpath.getName(), false); + // Add all the classpath files to the RAR files. + for (File classpath : classpaths) { + if (!classpath.isDirectory()) { + tranferFile(classpath, jos, classpath.getName(), false); + } } } - jos.close(); return rar.toURI(); } @@ -200,13 +199,16 @@ void transferDir(File basedir, File dir, JarOutputStream jos, String entryNamePr if (dir == null || jos == null) { return; } - for (File f : dir.listFiles()) { - if (f.isFile()) { - String entryName = entryNamePrefix + - f.getPath().substring(basedir.getPath().length() + 1); - tranferFile(f, jos, entryName, false); - } else { - transferDir(basedir, f, jos, entryNamePrefix); + File[] files = dir.listFiles(); + if (files != null) { + for (File f : files) { + if (f.isFile()) { + String entryName = entryNamePrefix + + f.getPath().substring(basedir.getPath().length() + 1); + tranferFile(f, jos, entryName, false); + } else { + transferDir(basedir, f, jos, entryNamePrefix); + } } } } @@ -230,18 +232,17 @@ void transferFile(File file, JarOutputStream jos, String entryName) throws IOExc } catch (ZipException ex) { return; } - FileInputStream fin = new FileInputStream(file); - transferContents(fin, jos); - jos.closeEntry(); + try(FileInputStream fin = new FileInputStream(file)) { + transferContents(fin, jos); + jos.closeEntry(); + } } void tranferEntries(File file, JarOutputStream jos) throws IOException { if (file == null || jos == null) { return; } - JarFile jarFile = null; - try { - jarFile = new JarFile(file); + try (JarFile jarFile = new JarFile(file)) { Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); @@ -257,15 +258,6 @@ void tranferEntries(File file, JarOutputStream jos) throws IOException { } } } - } finally { - if (jarFile != null) { - try { - jarFile.close(); - } catch (IOException ioe) { - //ignore - } - } - } } @@ -284,13 +276,16 @@ void transferContents(InputStream fin, JarOutputStream jos) private List getFileNames(File directory) { if (directory != null && directory.exists() && directory.isDirectory()) { - return getFileNames(Arrays.asList(directory.listFiles())); + File[] files = directory.listFiles(); + if (files != null) { + return getFileNames(Arrays.asList(files)); + } } - return Collections.EMPTY_LIST; + return Collections.emptyList(); } private List getFileNames(List files) { - List result = new ArrayList(); + List result = new ArrayList<>(); for (File f : files) { if (!f.isDirectory()) { result.add(f.getName()); @@ -299,7 +294,7 @@ private List getFileNames(List files) { return result; } - private static final List EXCLUDE_JAR_ENTRIES = new ArrayList(); + private static final List EXCLUDE_JAR_ENTRIES = new ArrayList<>(); static { EXCLUDE_JAR_ENTRIES.add(Pattern.compile("META-INF/MANIFEST\\.MF")); From db37b7bb406c8c095c439e92d1ca07bcffdd3ebc Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Wed, 27 Mar 2019 15:19:56 +0100 Subject: [PATCH 081/108] PAYARA-3466 annotations are inherited from superclass and interfaces, TCK passes --- .../impl/model/util/AnnotationInfo.java | 162 ++++++++++++++++++ .../openapi/impl/model/util/ModelUtils.java | 125 ++++++++------ .../impl/processor/ApplicationProcessor.java | 24 ++- .../openapi/impl/visitor/OpenApiWalker.java | 152 +++++++--------- .../test/app/OpenApiApplicationTest.java | 4 - .../app/application/HelloControllerTest.java | 69 ++++++++ 6 files changed, 375 insertions(+), 161 deletions(-) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HelloControllerTest.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java new file mode 100644 index 00000000000..9a946dc6363 --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java @@ -0,0 +1,162 @@ +package fish.payara.microprofile.openapi.impl.model.util; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Executable; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Represents the aggregated annotations on a type, its fields and methods including annotations "inherited" from + * super-classes and implemented interfaces. + */ +public final class AnnotationInfo { + + private static final Map, AnnotationInfo> TYPES = new ConcurrentHashMap<>(); + + @SuppressWarnings("unchecked") + public static AnnotationInfo valueOf(Class type) { + return (AnnotationInfo) TYPES.computeIfAbsent(type, key -> new AnnotationInfo<>(key)); + } + + private final Class type; + private final Map, Annotation> typeAnnotations = new ConcurrentHashMap<>(); + private final Map, Annotation>> fieldAnnotations = new ConcurrentHashMap<>(); + private final Map, Annotation>> methodAnnotations = new ConcurrentHashMap<>(); + private final Map, Annotation>> methodParameterAnnotations = new ConcurrentHashMap<>(); + + private AnnotationInfo(Class type) { + this.type = type; + init(type); + } + + public Class getType() { + return type; + } + + @SuppressWarnings("unchecked") + public A getAnnotation(Class annotationType) { + return (A) typeAnnotations.get(annotationType); + } + + @SuppressWarnings("unchecked") + public A getAnnotation(Class annotationType, Field field) { + return (A) fieldAnnotations.get(field.getName()).get(annotationType); + } + + @SuppressWarnings("unchecked") + public A getAnnotation(Class annotationType, Method method) { + return (A) methodAnnotations.get(getSignature(method)).get(annotationType); + } + + @SuppressWarnings("unchecked") + public A getAnnotation(Class annotationType, Parameter parameter) { + return (A) methodParameterAnnotations.get(getIdentifier(parameter)).get(annotationType); + } + + public A getAnnotation(Class annotationType, AnnotatedElement element) { + Class kind = element.getClass(); + if (kind == Class.class) { + return getAnnotation(annotationType); + } + if (kind == Field.class) { + return getAnnotation(annotationType, (Field) element); + } + if (kind == Method.class) { + return getAnnotation(annotationType, (Method) element); + } + if (kind == Parameter.class) { + return getAnnotation(annotationType, (Parameter) element); + } + return null; + } + + public boolean isAnnotationPresent(Class annotationType) { + return getAnnotation(annotationType) != null; + } + + public boolean isAnnotationPresent(Class annotationType, Field field) { + return getAnnotation(annotationType, field) != null; + } + + public boolean isAnnotationPresent(Class annotationType, Method method) { + return getAnnotation(annotationType, method) != null; + } + + public boolean isAnnotationPresent(Class annotationType, Parameter parameter) { + return getAnnotation(annotationType, parameter) != null; + } + + public boolean isAnnotationPresent(Class annotationType, AnnotatedElement element) { + return getAnnotation(annotationType, element) != null; + } + + @SafeVarargs + public final boolean anyAnnotationPresent(AnnotatedElement element, Class... annotationTypes) { + for (Class annotationType : annotationTypes) { + if (isAnnotationPresent(annotationType, element)) { + return true; + } + } + return false; + } + + public int getAnnotationCount(Parameter parameter) { + return methodParameterAnnotations.get(getIdentifier(parameter)).size(); + } + + private void init(Class type) { + // recurse first so that re-stated annotations "override" + Class supertype = type.getSuperclass(); + if (supertype != null && supertype != Object.class) { + init(supertype); + } + for (Class implementedInterface : type.getInterfaces()) { + init(implementedInterface); + } + // collect annotations + putAll(type.getDeclaredAnnotations(), typeAnnotations); + for (Field field : type.getDeclaredFields()) { + putAll(field.getDeclaredAnnotations(), + fieldAnnotations.computeIfAbsent(field.getName(), key -> new ConcurrentHashMap<>())); + } + for (Method method : type.getDeclaredMethods()) { + putAll(method.getDeclaredAnnotations(), + methodAnnotations.computeIfAbsent(getSignature(method), key -> new ConcurrentHashMap<>())); + for (Parameter parameter : method.getParameters()) { + putAll(parameter.getDeclaredAnnotations(), + methodParameterAnnotations.computeIfAbsent(getIdentifier(parameter), key -> new ConcurrentHashMap<>())); + } + } + } + + private static void putAll(Annotation[] annotations, Map, Annotation> map) { + for (Annotation a : annotations) { + map.put(a.annotationType(), a); + } + } + + private static String getIdentifier(Parameter parameter) { + try { + java.lang.reflect.Field index = parameter.getClass().getDeclaredField("index"); + index.setAccessible(true); + return getSignature(parameter.getDeclaringExecutable()) + "#" + index.getInt(parameter); + } catch (Exception e) { + return getSignature(parameter.getDeclaringExecutable()) + "#" + parameter.toString(); + } + } + + private static String getSignature(Executable method) { + StringBuilder signature = new StringBuilder(); + signature.append(method.getName()); + signature.append('('); + for (Class parameterType : method.getParameterTypes()) { + signature.append(parameterType.getName()).append(", "); + } + signature.append(')'); + return signature.toString(); + } +} \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java index c20794d73bb..12bba2e034b 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java @@ -135,25 +135,26 @@ public static String normaliseUrl(String path) { * none. */ public static HttpMethod getHttpMethod(Method method) { - if (method.isAnnotationPresent(GET.class)) { + AnnotationInfo annotations = AnnotationInfo.valueOf(method.getDeclaringClass()); + if (annotations.isAnnotationPresent(GET.class, method)) { return HttpMethod.GET; } - if (method.isAnnotationPresent(POST.class)) { + if (annotations.isAnnotationPresent(POST.class, method)) { return HttpMethod.POST; } - if (method.isAnnotationPresent(PUT.class)) { + if (annotations.isAnnotationPresent(PUT.class, method)) { return HttpMethod.PUT; } - if (method.isAnnotationPresent(DELETE.class)) { + if (annotations.isAnnotationPresent(DELETE.class, method)) { return HttpMethod.DELETE; } - if (method.isAnnotationPresent(HEAD.class)) { + if (annotations.isAnnotationPresent(HEAD.class, method)) { return HttpMethod.HEAD; } - if (method.isAnnotationPresent(OPTIONS.class)) { + if (annotations.isAnnotationPresent(OPTIONS.class, method)) { return HttpMethod.OPTIONS; } - if (method.isAnnotationPresent(PATCH.class)) { + if (annotations.isAnnotationPresent(PATCH.class, method)) { return HttpMethod.PATCH; } return null; @@ -326,67 +327,70 @@ public static SchemaType getParentSchemaType(SchemaType type1, SchemaType type2) } public static boolean isRequestBody(Parameter parameter) { - if (parameter.getDeclaredAnnotations().length == 0) { + AnnotationInfo annotations = AnnotationInfo.valueOf(parameter.getDeclaringExecutable().getDeclaringClass()); + if (annotations.getAnnotationCount(parameter) == 0) { return true; } - if (parameter.isAnnotationPresent(FormParam.class)) { + if (annotations.isAnnotationPresent(FormParam.class, parameter)) { return false; } - if (parameter.isAnnotationPresent(QueryParam.class)) { + if (annotations.isAnnotationPresent(QueryParam.class, parameter)) { return false; } - if (parameter.isAnnotationPresent(MatrixParam.class)) { + if (annotations.isAnnotationPresent(MatrixParam.class, parameter)) { return false; } - if (parameter.isAnnotationPresent(BeanParam.class)) { + if (annotations.isAnnotationPresent(BeanParam.class, parameter)) { return false; } - if (parameter.isAnnotationPresent(HeaderParam.class)) { + if (annotations.isAnnotationPresent(HeaderParam.class, parameter)) { return false; } - if (parameter.isAnnotationPresent(PathParam.class)) { + if (annotations.isAnnotationPresent(PathParam.class, parameter)) { return false; } - if (parameter.isAnnotationPresent(CookieParam.class)) { + if (annotations.isAnnotationPresent(CookieParam.class, parameter)) { return false; } - if (parameter.isAnnotationPresent(Context.class)) { + if (annotations.isAnnotationPresent(Context.class, parameter)) { return false; } - if (parameter.isAnnotationPresent(Inject.class)) { + if (annotations.isAnnotationPresent(Inject.class, parameter)) { return false; } - if (parameter.isAnnotationPresent(Provider.class)) { + if (annotations.isAnnotationPresent(Provider.class, parameter)) { return false; } return true; } public static In getParameterType(Parameter parameter) { - if (parameter.isAnnotationPresent(PathParam.class)) { + AnnotationInfo annotations = AnnotationInfo.valueOf(parameter.getDeclaringExecutable().getDeclaringClass()); + if (annotations.isAnnotationPresent(PathParam.class, parameter)) { return In.PATH; } - if (parameter.isAnnotationPresent(QueryParam.class)) { + if (annotations.isAnnotationPresent(QueryParam.class, parameter)) { return In.QUERY; } - if (parameter.isAnnotationPresent(HeaderParam.class)) { + if (annotations.isAnnotationPresent(HeaderParam.class, parameter)) { return In.HEADER; } - if (parameter.isAnnotationPresent(CookieParam.class)) { + if (annotations.isAnnotationPresent(CookieParam.class, parameter)) { return In.COOKIE; } return null; } public static String getParameterName(Parameter parameter) { - if (parameter.isAnnotationPresent(PathParam.class)) { - return parameter.getDeclaredAnnotation(PathParam.class).value(); - } else if (parameter.isAnnotationPresent(QueryParam.class)) { - return parameter.getDeclaredAnnotation(QueryParam.class).value(); - } else if (parameter.isAnnotationPresent(HeaderParam.class)) { - return parameter.getDeclaredAnnotation(HeaderParam.class).value(); - } else if (parameter.isAnnotationPresent(CookieParam.class)) { - return parameter.getDeclaredAnnotation(CookieParam.class).value(); + AnnotationInfo annotations = AnnotationInfo.valueOf(parameter.getDeclaringExecutable().getDeclaringClass()); + if (annotations.isAnnotationPresent(PathParam.class, parameter)) { + return annotations.getAnnotation(PathParam.class, parameter).value(); + } else if (annotations.isAnnotationPresent(QueryParam.class, parameter)) { + return annotations.getAnnotation(QueryParam.class, parameter).value(); + } else if (annotations.isAnnotationPresent(HeaderParam.class, parameter)) { + return annotations.getAnnotation(HeaderParam.class, parameter).value(); + } else if (annotations.isAnnotationPresent(CookieParam.class, parameter)) { + return annotations.getAnnotation(CookieParam.class, parameter).value(); } return null; } @@ -555,7 +559,7 @@ else if (newValue instanceof Constructible) { } } } - + public static org.eclipse.microprofile.openapi.models.Operation getOperation(Method method, OpenAPI api, Map>> resourceMapping) { String path = getResourcePath(method, resourceMapping); @@ -570,37 +574,44 @@ public static org.eclipse.microprofile.openapi.models.Operation getOperation(Met } public static String getResourcePath(GenericDeclaration declaration, Map>> resourceMapping) { - String path = null; if (declaration instanceof Method) { - Method method = (Method) declaration; - - // If the method is a valid resource - if (method.isAnnotationPresent(GET.class) || method.isAnnotationPresent(POST.class) - || method.isAnnotationPresent(PUT.class) || method.isAnnotationPresent(DELETE.class) - || method.isAnnotationPresent(HEAD.class) || method.isAnnotationPresent(OPTIONS.class) - || method.isAnnotationPresent(PATCH.class)) { - if (method.isAnnotationPresent(Path.class)) { - path = getResourcePath(method.getDeclaringClass(), resourceMapping) + "/" - + method.getDeclaredAnnotation(Path.class).value(); - } else { - path = getResourcePath(method.getDeclaringClass(), resourceMapping); + return getResourcePath((Method) declaration, resourceMapping); + } + if (declaration instanceof Class) { + return getResourcePath((Class) declaration, resourceMapping); + } + return null; + } + + private static String getResourcePath(Class clazz, Map>> resourceMapping) { + // If the class is a resource and contains a mapping + AnnotationInfo annotations = AnnotationInfo.valueOf(clazz); + if (annotations.isAnnotationPresent(Path.class)) { + for (Map.Entry>> entry : resourceMapping.entrySet()) { + if (entry.getValue() != null && entry.getValue().contains(clazz)) { + return normaliseUrl(entry.getKey() + "/" + annotations.getAnnotation(Path.class).value()); } } } - if (declaration instanceof Class) { - Class clazz = (Class) declaration; - clazz.toString(); - + return null; + } - // If the class is a resource and contains a mapping - if (clazz.isAnnotationPresent(Path.class)) { - for (Map.Entry>> entry : resourceMapping.entrySet()) { - if (entry.getValue() != null && entry.getValue().contains(clazz)) { - path = entry.getKey() + "/" + clazz.getDeclaredAnnotation(Path.class).value(); - } - } + private static String getResourcePath(Method method, Map>> resourceMapping) { + AnnotationInfo annotations = AnnotationInfo.valueOf(method.getDeclaringClass()); + if (annotations.isAnnotationPresent(GET.class, method) + || annotations.isAnnotationPresent(POST.class, method) + || annotations.isAnnotationPresent(PUT.class, method) + || annotations.isAnnotationPresent(DELETE.class, method) + || annotations.isAnnotationPresent(HEAD.class, method) + || annotations.isAnnotationPresent(OPTIONS.class, method) + || annotations.isAnnotationPresent(PATCH.class, method)) { + if (annotations.isAnnotationPresent(Path.class, method)) { + // If the method is a valid resource + return normaliseUrl(getResourcePath(method.getDeclaringClass(), resourceMapping) + "/" + + annotations.getAnnotation(Path.class, method).value()); } + return normaliseUrl(getResourcePath(method.getDeclaringClass(), resourceMapping)); } - return normaliseUrl(path); - } + return null; + } } \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java index 37801f59d21..981c2bd05fb 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java @@ -75,7 +75,6 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.Application; -import org.eclipse.microprofile.openapi.annotations.Components; import org.eclipse.microprofile.openapi.annotations.ExternalDocumentation; import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition; import org.eclipse.microprofile.openapi.annotations.Operation; @@ -110,7 +109,6 @@ import fish.payara.microprofile.openapi.api.visitor.ApiVisitor; import fish.payara.microprofile.openapi.api.visitor.ApiWalker; import fish.payara.microprofile.openapi.impl.config.OpenApiConfiguration; -import fish.payara.microprofile.openapi.impl.model.ComponentsImpl; import fish.payara.microprofile.openapi.impl.model.ExtensibleImpl; import fish.payara.microprofile.openapi.impl.model.ExternalDocumentationImpl; import fish.payara.microprofile.openapi.impl.model.OpenAPIImpl; @@ -128,6 +126,7 @@ import fish.payara.microprofile.openapi.impl.model.security.SecuritySchemeImpl; import fish.payara.microprofile.openapi.impl.model.servers.ServerImpl; import fish.payara.microprofile.openapi.impl.model.tags.TagImpl; +import fish.payara.microprofile.openapi.impl.model.util.AnnotationInfo; import fish.payara.microprofile.openapi.impl.model.util.ModelUtils; import fish.payara.microprofile.openapi.impl.visitor.OpenApiContext; import fish.payara.microprofile.openapi.impl.visitor.OpenApiWalker; @@ -155,7 +154,10 @@ public class ApplicationProcessor implements OASProcessor, ApiVisitor { */ public ApplicationProcessor(Set> appClasses) { this.classes = appClasses; - addInnerClasses(); + this.classes.removeIf(cls -> cls.isInterface() || Modifier.isAbstract(cls.getModifiers())); + if (classes != null) { + addInnerClasses(); + } } private void addInnerClasses() { @@ -166,9 +168,11 @@ private void addInnerClasses() { } private void addInnerClasses(Class topLevelClass) { - classes.addAll(Arrays.asList(topLevelClass.getDeclaredClasses())); - if (topLevelClass.getSuperclass() != Object.class) { - addInnerClasses(topLevelClass.getSuperclass()); + if (topLevelClass != null) { + classes.addAll(Arrays.asList(topLevelClass.getDeclaredClasses())); + if (topLevelClass.getSuperclass() != Object.class) { + addInnerClasses(topLevelClass.getSuperclass()); + } } } @@ -705,13 +709,15 @@ public void visitCallbacks(Callbacks callbacks, AnnotatedElement element, ApiCon @Override public void visitRequestBody(RequestBody requestBody, AnnotatedElement element, ApiContext context) { - if (element instanceof Method) { + if (element instanceof Method || element instanceof java.lang.reflect.Parameter) { org.eclipse.microprofile.openapi.models.parameters.RequestBody currentRequestBody = context .getWorkingOperation().getRequestBody(); if (currentRequestBody != null || element instanceof java.lang.reflect.Parameter) { RequestBodyImpl.merge(requestBody, currentRequestBody, true, context.getApi().getComponents().getSchemas()); } + } else { + System.out.println("Ignored"); } } @@ -1008,7 +1014,7 @@ private org.eclipse.microprofile.openapi.models.responses.APIResponse insertDefa defaultResponse.getContent().addMediaType(javax.ws.rs.core.MediaType.WILDCARD, mediaType); // Add the default response - operation.setResponses(new APIResponsesImpl().addApiResponse( + operation.setResponses(new APIResponsesImpl().addAPIResponse( org.eclipse.microprofile.openapi.models.responses.APIResponses.DEFAULT, defaultResponse)); return defaultResponse; } @@ -1104,7 +1110,7 @@ private boolean insertObjectReference(ApiContext context, Reference referee, referee.setRef(referenceClass.getSimpleName()); // Create the schema - visitSchema(referenceClass.getDeclaredAnnotation(Schema.class), referenceClass, context); + visitSchema(AnnotationInfo.valueOf(referenceClass).getAnnotation(Schema.class), referenceClass, context); return true; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java index 73be00453c1..b28845eecfa 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java @@ -46,7 +46,6 @@ import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -95,6 +94,7 @@ import fish.payara.microprofile.openapi.api.visitor.ApiVisitor; import fish.payara.microprofile.openapi.api.visitor.ApiVisitor.VisitorFunction; import fish.payara.microprofile.openapi.api.visitor.ApiWalker; +import fish.payara.microprofile.openapi.impl.model.util.AnnotationInfo; /** * A walker that visits each annotation and passes it to the visitor. @@ -133,8 +133,8 @@ public OpenApiWalker(OpenAPI api, Set> allowedClasses, Map void processAnnotations( - Class annotationClass, VisitorFunction annotationFunction, Class altClass, - VisitorFunction altFunction, boolean allowInterfaces) { + @SafeVarargs + private final void processAnnotations( + Class annotationClass, VisitorFunction annotationFunction, + Class... alternatives) { for (Class clazz : classes) { - - // Don't read interfaces if the annotation should only be read from concrete classes - if (!allowInterfaces && (Modifier.isAbstract(clazz.getModifiers()) || clazz.isInterface())) { - continue; - } - - processAnnotation(clazz, annotationClass, annotationFunction, altClass, altFunction, - new OpenApiContext(api, getResourcePath(clazz, resourceMapping))); - - for (Field field : clazz.getDeclaredFields()) { - processAnnotation(field, annotationClass, annotationFunction, altClass, altFunction, - new OpenApiContext(api, null)); - } - - for (Method method : clazz.getDeclaredMethods()) { - - processAnnotation(method, annotationClass, annotationFunction, altClass, altFunction, - new OpenApiContext(api, getResourcePath(method, resourceMapping), getOperation(method, api, resourceMapping))); - - for (java.lang.reflect.Parameter parameter : method.getParameters()) { - processAnnotation(parameter, annotationClass, annotationFunction, altClass, altFunction, - new OpenApiContext(api, getResourcePath(method, resourceMapping), getOperation(method, api, resourceMapping))); - } - } + processAnnotation(clazz, annotationClass, annotationFunction, alternatives); } } - private void processAnnotations(Class annotationClass, - VisitorFunction function) { - processAnnotations(annotationClass, function, false); - } + @SafeVarargs + private final void processAnnotation( + Class annotatedClass, Class annotationClass, VisitorFunction annotationFunction, + Class... alternatives) { + AnnotationInfo annotations = AnnotationInfo.valueOf(annotatedClass); + processAnnotation(annotatedClass, annotationClass, annotationFunction, annotations, + new OpenApiContext(api, getResourcePath(annotatedClass, resourceMapping)), alternatives); + + for (Field field : annotatedClass.getDeclaredFields()) { + processAnnotation(field, annotationClass, annotationFunction, annotations, + new OpenApiContext(api, null), alternatives); + } - private void processAnnotations(Class annotationClass, - VisitorFunction function, boolean allowInterfaces) { - processAnnotations(annotationClass, function, null, null, allowInterfaces); - } + for (final Method method : annotatedClass.getDeclaredMethods()) { + OpenApiContext context = new OpenApiContext(api, + getResourcePath(method, resourceMapping), + getOperation(method, api, resourceMapping)); + processAnnotation(method, annotationClass, annotationFunction, annotations, context, alternatives); - private void processAnnotations( - Class annotationClass, VisitorFunction annotationFunction, Class altClass, - VisitorFunction altFunction) { - processAnnotations(annotationClass, annotationFunction, altClass, altFunction, false); + for (java.lang.reflect.Parameter parameter : method.getParameters()) { + processAnnotation(parameter, annotationClass, annotationFunction, annotations, context, alternatives); + } + } } @SuppressWarnings("unchecked") - private void processAnnotation( - AnnotatedElement element, Class annotationClass, VisitorFunction annotationFunction, - Class altClass, VisitorFunction altFunction, ApiContext context) { + @SafeVarargs + private static void processAnnotation( + AnnotatedElement element, Class annotationClass, VisitorFunction annotationFunction, + AnnotationInfo annotations, ApiContext context, Class... alternatives) { // If it's just the one annotation class - if (altClass == null) { - // Check the element - if (element.isAnnotationPresent(annotationClass)) { - annotationFunction.apply(element.getDeclaredAnnotation(annotationClass), (E) element, context); - } else if (element instanceof Method - && Method.class.cast(element).getDeclaringClass().isAnnotationPresent(annotationClass)) { - // If the method isn't annotated, inherit the class annotation - if (context.getPath() != null) { - annotationFunction.apply( - Method.class.cast(element).getDeclaringClass().getDeclaredAnnotation(annotationClass), - (E) element, context); - } - } - } else { - // If it's annotated with both - if (element.isAnnotationPresent(annotationClass) || element.isAnnotationPresent(altClass)) { - if (element.isAnnotationPresent(annotationClass)) { - annotationFunction.apply(element.getDeclaredAnnotation(annotationClass), (E) element, context); - } - if (element.isAnnotationPresent(altClass)) { - altFunction.apply(element.getDeclaredAnnotation(altClass), (E) element, context); - } - } else if (element instanceof Method && context.getPath() != null) { - Class declaringClass = Method.class.cast(element).getDeclaringClass(); - if (declaringClass.isAnnotationPresent(annotationClass)) { - annotationFunction.apply(declaringClass.getDeclaredAnnotation(annotationClass), (E) element, - context); - } - if (declaringClass.isAnnotationPresent(altClass)) { - altFunction.apply(declaringClass.getDeclaredAnnotation(altClass), (E) element, context); - } + // Check the element + if (annotations.isAnnotationPresent(annotationClass, element)) { + annotationFunction.apply(annotations.getAnnotation(annotationClass, element), (E) element, context); + } else if (element instanceof Method && annotations.isAnnotationPresent(annotationClass) + && !annotations.anyAnnotationPresent(element, alternatives)) { + // If the method isn't annotated, inherit the class annotation + if (context.getPath() != null) { + annotationFunction.apply(annotations.getAnnotation(annotationClass), (E) element, context); } } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenApiApplicationTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenApiApplicationTest.java index aff059619e6..2f52add842e 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenApiApplicationTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/OpenApiApplicationTest.java @@ -42,10 +42,6 @@ import static fish.payara.microprofile.openapi.test.util.JsonUtils.toJson; import static org.junit.Assert.assertNotNull; -import java.util.Optional; - -import org.eclipse.microprofile.config.Config; -import org.eclipse.microprofile.config.spi.ConfigSource; import org.eclipse.microprofile.openapi.OASFilter; import org.eclipse.microprofile.openapi.models.OpenAPI; import org.junit.Before; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HelloControllerTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HelloControllerTest.java new file mode 100644 index 00000000000..3f60c8b473d --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HelloControllerTest.java @@ -0,0 +1,69 @@ +package fish.payara.microprofile.openapi.test.app.application; + +import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +import fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest; + +/** + * Test for scenario given in PAYARA-3162 (Annotations from interfaces were not recognised). + **/ +public class HelloControllerTest extends OpenApiApplicationTest { + + interface HelloResource { + + @GET + String sayHello(); + } + + @Path("/hello") + static class HelloController implements HelloResource { + @Override + public String sayHello() { + return "Hello World"; + } + } + + @Test + public void methodsCanBeAnnotatedOnInterface() { + JsonNode sayHello = path(getOpenAPIJson(), "paths./test/hello.get"); + assertNotNull(sayHello); + assertEquals("sayHello", sayHello.get("operationId").textValue()); + JsonNode schema = path(sayHello, "responses.default.content.*/*.schema"); + assertNotNull(schema); + assertEquals("string", schema.get("type").textValue()); + } + + @Path("/welcome") + interface WelcomeResource { + + @GET + String sayWelcome(); + } + + static class WelcomeController implements WelcomeResource { + + @Override + public String sayWelcome() { + return "Welcome!"; + } + } + + @Test + public void methodsAndPathCanBeAnnotatedOnInterface() { + JsonNode sayWelcome = path(getOpenAPIJson(), "paths./test/welcome.get"); + assertNotNull(sayWelcome); + assertEquals("sayWelcome", sayWelcome.get("operationId").textValue()); + JsonNode schema = path(sayWelcome, "responses.default.content.*/*.schema"); + assertNotNull(schema); + assertEquals("string", schema.get("type").textValue()); + } +} From a254f908e4bc2f860fe06da3b409787dc9159c58 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Wed, 27 Mar 2019 15:57:08 +0100 Subject: [PATCH 082/108] PAYARA-3466 added tests for hidden property + cleanup --- .../impl/model/util/AnnotationInfo.java | 2 +- .../openapi/impl/model/util/ModelUtils.java | 43 +++---------------- .../impl/processor/ApplicationProcessor.java | 2 - .../openapi/impl/visitor/OpenApiWalker.java | 2 +- .../test/app/application/HiddenTest.java | 43 +++++++++++++++++++ 5 files changed, 50 insertions(+), 42 deletions(-) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HiddenTest.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java index 9a946dc6363..5839c4975e0 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java @@ -95,7 +95,7 @@ public boolean isAnnotationPresent(Class annotationType, A } @SafeVarargs - public final boolean anyAnnotationPresent(AnnotatedElement element, Class... annotationTypes) { + public final boolean isAnyAnnotationPresent(AnnotatedElement element, Class... annotationTypes) { for (Class annotationType : annotationTypes) { if (isAnnotationPresent(annotationType, element)) { return true; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java index 12bba2e034b..fa10e7d3a28 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java @@ -331,37 +331,9 @@ public static boolean isRequestBody(Parameter parameter) { if (annotations.getAnnotationCount(parameter) == 0) { return true; } - if (annotations.isAnnotationPresent(FormParam.class, parameter)) { - return false; - } - if (annotations.isAnnotationPresent(QueryParam.class, parameter)) { - return false; - } - if (annotations.isAnnotationPresent(MatrixParam.class, parameter)) { - return false; - } - if (annotations.isAnnotationPresent(BeanParam.class, parameter)) { - return false; - } - if (annotations.isAnnotationPresent(HeaderParam.class, parameter)) { - return false; - } - if (annotations.isAnnotationPresent(PathParam.class, parameter)) { - return false; - } - if (annotations.isAnnotationPresent(CookieParam.class, parameter)) { - return false; - } - if (annotations.isAnnotationPresent(Context.class, parameter)) { - return false; - } - if (annotations.isAnnotationPresent(Inject.class, parameter)) { - return false; - } - if (annotations.isAnnotationPresent(Provider.class, parameter)) { - return false; - } - return true; + return !annotations.isAnyAnnotationPresent(parameter, FormParam.class, QueryParam.class, MatrixParam.class, + BeanParam.class, HeaderParam.class, PathParam.class, CookieParam.class, Context.class, Inject.class, + Provider.class); } public static In getParameterType(Parameter parameter) { @@ -598,13 +570,8 @@ private static String getResourcePath(Class clazz, Map>> private static String getResourcePath(Method method, Map>> resourceMapping) { AnnotationInfo annotations = AnnotationInfo.valueOf(method.getDeclaringClass()); - if (annotations.isAnnotationPresent(GET.class, method) - || annotations.isAnnotationPresent(POST.class, method) - || annotations.isAnnotationPresent(PUT.class, method) - || annotations.isAnnotationPresent(DELETE.class, method) - || annotations.isAnnotationPresent(HEAD.class, method) - || annotations.isAnnotationPresent(OPTIONS.class, method) - || annotations.isAnnotationPresent(PATCH.class, method)) { + if (annotations.isAnyAnnotationPresent(method, + GET.class, POST.class, PUT.class, DELETE.class, HEAD.class, OPTIONS.class, PATCH.class)) { if (annotations.isAnnotationPresent(Path.class, method)) { // If the method is a valid resource return normaliseUrl(getResourcePath(method.getDeclaringClass(), resourceMapping) + "/" diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java index 981c2bd05fb..9e16fbdad82 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java @@ -716,8 +716,6 @@ public void visitRequestBody(RequestBody requestBody, AnnotatedElement element, RequestBodyImpl.merge(requestBody, currentRequestBody, true, context.getApi().getComponents().getSchemas()); } - } else { - System.out.println("Ignored"); } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java index b28845eecfa..251f9605c12 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java @@ -225,7 +225,7 @@ private static void processAn if (annotations.isAnnotationPresent(annotationClass, element)) { annotationFunction.apply(annotations.getAnnotation(annotationClass, element), (E) element, context); } else if (element instanceof Method && annotations.isAnnotationPresent(annotationClass) - && !annotations.anyAnnotationPresent(element, alternatives)) { + && !annotations.isAnyAnnotationPresent(element, alternatives)) { // If the method isn't annotated, inherit the class annotation if (context.getPath() != null) { annotationFunction.apply(annotations.getAnnotation(annotationClass), (E) element, context); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HiddenTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HiddenTest.java new file mode 100644 index 00000000000..6ef25162f3b --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HiddenTest.java @@ -0,0 +1,43 @@ +package fish.payara.microprofile.openapi.test.app.application; + +import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; +import static org.junit.Assert.assertNotNull; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.junit.Test; + +import fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest; + +/** + * Test to verify that using {@code hidden} does not cause errors as suggested by PAYARA-3259. + */ +@Path("/example") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class HiddenTest extends OpenApiApplicationTest { + + @GET + @Path("/{name}") + @Operation(hidden = true) + public Response hello(@PathParam("name") String name) { + JsonObject message = Json.createObjectBuilder() + .add("message", "hello" + name) + .build(); + return Response.ok(message).build(); + } + + @Test + public void hiddenPropertyDoesNotCauseErrors() { + assertNotNull(path(getOpenAPIJson(), "paths./test/example/{name}")); + } +} From eb766e9fbfd4d4e1a2f62a5163eebbe683b44a81 Mon Sep 17 00:00:00 2001 From: Andrew Pielage Date: Wed, 27 Mar 2019 17:19:31 +0000 Subject: [PATCH 083/108] PAYARA-3676 Much more aggressive use of Jline --- .../enterprise/admin/cli/LoginCommand.java | 38 +++++--- .../admin/cli/remote/RemoteCLICommand.java | 92 +++++++++++-------- .../admin/cli/remote/RemoteCommand.java | 89 ++++++++++-------- .../cli/ChangeAdminPasswordCommand.java | 33 ++++--- .../servermgmt/cli/CreateDomainCommand.java | 39 ++++---- nucleus/admin/util/pom.xml | 5 + .../admin/util/AsadminTrustManager.java | 30 ++++-- .../cli/cluster/LocalInstanceCommand.java | 58 ++++++------ .../admin/cli/cluster/SetupLocalDcom.java | 25 ++++- .../admin/cli/cluster/SetupSshKey.java | 33 ++++--- nucleus/common/common-util/pom.xml | 5 + .../security/store/AsadminSecurityUtil.java | 18 +++- 12 files changed, 290 insertions(+), 175 deletions(-) diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java index 1ad891a3201..21249494fe2 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java @@ -47,9 +47,10 @@ import com.sun.enterprise.admin.cli.remote.*; import com.sun.enterprise.universal.i18n.LocalStringsImpl; import com.sun.enterprise.util.SystemPropertyConstants; -import java.io.Console; import java.io.IOException; +import java.util.logging.Level; +import jline.console.ConsoleReader; import org.glassfish.api.admin.*; import org.glassfish.hk2.api.PerLookup; import org.jvnet.hk2.annotations.*; @@ -120,21 +121,32 @@ protected int executeCommand() throws CommandException, CommandValidationExcepti * Prompt for the admin user name. */ private String getAdminUser() { - Console cons = System.console(); String user = null; - String defuser = programOpts.getUser(); - if (defuser == null) { - defuser = SystemPropertyConstants.DEFAULT_ADMIN_USER; - } - if (cons != null) { - cons.printf("%s", strings.get("AdminUserPrompt", defuser)); - String val = cons.readLine(); - if (val != null && val.length() > 0){ - user = val; - } else { - user = defuser; + + try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { + String defuser = programOpts.getUser(); + if (defuser == null) { + defuser = SystemPropertyConstants.DEFAULT_ADMIN_USER; } + if (cons != null) { + cons.setPrompt(strings.get("AdminUserPrompt", defuser)); + + String val = null; + try { + val = cons.readLine(); + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error reading input", ioe); + } + if (val != null && val.length() > 0){ + user = val; + } else { + user = defuser; + } + } + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error reading input", ioe); } + return user; } diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java index e6a3109dbf5..5139c8e3054 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java @@ -68,6 +68,8 @@ import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; + +import jline.console.ConsoleReader; import org.glassfish.api.ActionReport; import org.glassfish.api.ActionReport.ExitCode; import org.glassfish.api.admin.AdminCommandEventBroker; @@ -171,52 +173,62 @@ public void fetchCommandModel() throws CommandException { */ @Override protected boolean updateAuthentication() { - Console cons; - if (programOpts.isInteractive() && (cons = System.console()) != null) { - // if appropriate, tell the user why authentication failed - PasswordLocation pwloc = programOpts.getPasswordLocation(); - if (pwloc == PasswordLocation.PASSWORD_FILE) { - logger.log(Level.FINE, strings.get("BadPasswordFromFile", programOpts.getPasswordFile())); - } else if (pwloc == PasswordLocation.LOGIN_FILE) { - try { - LoginInfoStore store = LoginInfoStoreFactory.getDefaultStore(); - logger.log(Level.FINE, strings.get("BadPasswordFromLogin", store.getName())); - } - catch (StoreException ex) { - // ignore it + try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { + if (programOpts.isInteractive() && cons != null) { + // if appropriate, tell the user why authentication failed + PasswordLocation pwloc = programOpts.getPasswordLocation(); + if (pwloc == PasswordLocation.PASSWORD_FILE) { + logger.log(Level.FINE, strings.get("BadPasswordFromFile", programOpts.getPasswordFile())); + } else if (pwloc == PasswordLocation.LOGIN_FILE) { + try { + LoginInfoStore store = LoginInfoStoreFactory.getDefaultStore(); + logger.log(Level.FINE, strings.get("BadPasswordFromLogin", store.getName())); + } + catch (StoreException ex) { + // ignore it + } } - } - String user = null; - // only prompt for a user name if the user name is set to - // the default. otherwise, assume the user specified the - // correct username to begin with and all we need is the - // password. - if (programOpts.getUser() == null) { - cons.printf("%s ", strings.get("AdminUserPrompt")); - user = cons.readLine(); - if (user == null) { + String user = null; + // only prompt for a user name if the user name is set to + // the default. otherwise, assume the user specified the + // correct username to begin with and all we need is the + // password. + if (programOpts.getUser() == null) { + cons.setPrompt(strings.get("AdminUserPrompt")); + + try { + user = cons.readLine(); + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error reading input", ioe); + } + + if (user == null) { + return false; + } + } + char[] password; + String puser = ok(user) ? user : programOpts.getUser(); + if (ok(puser)) { + password = readPassword(strings.get("AdminUserPasswordPrompt", puser)); + } else { + password = readPassword(strings.get("AdminPasswordPrompt")); + } + if (password == null){ return false; } + if (ok(user)) { // if none entered, don't change + programOpts.setUser(user); + this.user = user; + } + programOpts.setPassword(password, PasswordLocation.USER); + this.password = password; + return true; } - char[] password; - String puser = ok(user) ? user : programOpts.getUser(); - if (ok(puser)) { - password = readPassword(strings.get("AdminUserPasswordPrompt", puser)); - } else { - password = readPassword(strings.get("AdminPasswordPrompt")); - } - if (password == null){ - return false; - } - if (ok(user)) { // if none entered, don't change - programOpts.setUser(user); - this.user = user; - } - programOpts.setPassword(password, PasswordLocation.USER); - this.password = password; - return true; + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error reading input", ioe); } + return false; } diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java index 2553b90aa9d..3f4f8a81e8c 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java @@ -61,6 +61,7 @@ import java.util.logging.Level; import java.util.logging.Logger; +import jline.console.ConsoleReader; import org.glassfish.api.admin.*; import org.glassfish.common.util.admin.ManPageFinder; import org.glassfish.hk2.api.ActiveDescriptor; @@ -134,50 +135,60 @@ public void fetchCommandModel() throws CommandException { */ @Override protected boolean updateAuthentication() { - Console cons; - if (programOpts.isInteractive() && (cons = System.console()) != null) { - // if appropriate, tell the user why authentication failed - PasswordLocation pwloc = programOpts.getPasswordLocation(); - if (pwloc == PasswordLocation.PASSWORD_FILE) { - logger.fine(strings.get("BadPasswordFromFile", programOpts.getPasswordFile())); - } else if (pwloc == PasswordLocation.LOGIN_FILE) { - try { - LoginInfoStore store = LoginInfoStoreFactory.getDefaultStore(); - logger.fine(strings.get("BadPasswordFromLogin", store.getName())); - } catch (StoreException ex) { - // ignore it + try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { + if (programOpts.isInteractive() && cons != null) { + // if appropriate, tell the user why authentication failed + PasswordLocation pwloc = programOpts.getPasswordLocation(); + if (pwloc == PasswordLocation.PASSWORD_FILE) { + logger.fine(strings.get("BadPasswordFromFile", programOpts.getPasswordFile())); + } else if (pwloc == PasswordLocation.LOGIN_FILE) { + try { + LoginInfoStore store = LoginInfoStoreFactory.getDefaultStore(); + logger.fine(strings.get("BadPasswordFromLogin", store.getName())); + } catch (StoreException ex) { + // ignore it + } } - } - String user = null; - // only prompt for a user name if the user name is set to - // the default. otherwise, assume the user specified the - // correct username to begin with and all we need is the - // password. - if (programOpts.getUser() == null) { - cons.printf("%s ", strings.get("AdminUserPrompt")); - user = cons.readLine(); - if (user == null) + String user = null; + // only prompt for a user name if the user name is set to + // the default. otherwise, assume the user specified the + // correct username to begin with and all we need is the + // password. + if (programOpts.getUser() == null) { + cons.setPrompt(strings.get("AdminUserPrompt")); + + try { + user = cons.readLine(); + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error reading input", ioe); + } + + if (user == null) + return false; + } + char[] password; + String puser = ok(user) ? user : programOpts.getUser(); + if (ok(puser)) { + password = readPassword(strings.get("AdminUserPasswordPrompt", puser)); + } else { + password = readPassword(strings.get("AdminPasswordPrompt")); + } + if (password == null) { return false; + } + if (ok(user)) { // if none entered, don't change + programOpts.setUser(user); + this.user = user; + } + programOpts.setPassword(password, PasswordLocation.USER); + this.password = password; + return true; } - char[] password; - String puser = ok(user) ? user : programOpts.getUser(); - if (ok(puser)) { - password = readPassword(strings.get("AdminUserPasswordPrompt", puser)); - } else { - password = readPassword(strings.get("AdminPasswordPrompt")); - } - if (password == null) { - return false; - } - if (ok(user)) { // if none entered, don't change - programOpts.setUser(user); - this.user = user; - } - programOpts.setPassword(password, PasswordLocation.USER); - this.password = password; - return true; + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error reading input", ioe); } + return false; } diff --git a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/ChangeAdminPasswordCommand.java b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/ChangeAdminPasswordCommand.java index 4b6b560c10e..4050657bde2 100644 --- a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/ChangeAdminPasswordCommand.java +++ b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/ChangeAdminPasswordCommand.java @@ -41,10 +41,11 @@ package com.sun.enterprise.admin.servermgmt.cli; -import java.io.Console; import java.io.IOException; import java.net.ConnectException; +import java.util.logging.Level; +import jline.console.ConsoleReader; import org.glassfish.api.I18n; import org.glassfish.api.Param; import org.glassfish.api.admin.CommandException; @@ -113,16 +114,26 @@ protected void validate() throws CommandException, CommandValidationException { if (programOpts.getUser() == null) { // prompt for it (if interactive) - Console cons = System.console(); - if (cons != null && programOpts.isInteractive()) { - cons.printf("%s", STRINGS.get("AdminUserDefaultPrompt", SystemPropertyConstants.DEFAULT_ADMIN_USER)); - String val = cons.readLine(); - if (ok(val)) - programOpts.setUser(val); - else - programOpts.setUser(SystemPropertyConstants.DEFAULT_ADMIN_USER); - } else { - throw new CommandValidationException(STRINGS.get("AdminUserRequired")); + try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { + if (cons != null && programOpts.isInteractive()) { + cons.setPrompt(STRINGS.get("AdminUserDefaultPrompt", + SystemPropertyConstants.DEFAULT_ADMIN_USER)); + + try { + String val = cons.readLine(); + if (ok(val)) { + programOpts.setUser(val); + } else { + programOpts.setUser(SystemPropertyConstants.DEFAULT_ADMIN_USER); + } + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error reading input", ioe); + } + } else { + throw new CommandValidationException(STRINGS.get("AdminUserRequired")); + } + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error instantiating console", ioe); } } diff --git a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java index e7ac6ea3d4a..a3d7564aeb3 100644 --- a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java +++ b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java @@ -68,14 +68,16 @@ import static com.sun.enterprise.util.net.NetUtils.isPortValid; import static java.util.logging.Level.FINER; -import java.io.Console; import java.io.File; +import java.io.IOException; import java.util.Collection; import java.util.LinkedHashSet; import java.util.Properties; import java.util.Set; import java.util.UUID; +import java.util.logging.Level; +import jline.console.ConsoleReader; import org.glassfish.api.Param; import org.glassfish.api.admin.CommandException; import org.glassfish.api.admin.CommandModel.ParamModel; @@ -221,24 +223,29 @@ protected void validate() throws CommandException, CommandValidationException { * The next prompted-for value will be the admin password, if required. */ if (programOpts.getUser() == null && !noPassword) { - // prompt for it (if interactive) - Console console = System.console(); - - if (console != null && programOpts.isInteractive()) { - console.printf("%s", STRINGS.get("AdminUserRequiredPrompt", SystemPropertyConstants.DEFAULT_ADMIN_USER)); - - String val = console.readLine(); - - if (ok(val)) { - programOpts.setUser(val); - if (adminPassword == null) { - char[] pwdArr = getAdminPassword(); - adminPassword = pwdArr != null ? new String(pwdArr) : null; + try (ConsoleReader console = new ConsoleReader(System.in, System.out, null)) { + if (console != null && programOpts.isInteractive()) { + console.setPrompt(STRINGS.get("AdminUserRequiredPrompt", SystemPropertyConstants.DEFAULT_ADMIN_USER)); + + try { + String val = console.readLine(); + + if (ok(val)) { + programOpts.setUser(val); + if (adminPassword == null) { + char[] pwdArr = getAdminPassword(); + adminPassword = pwdArr != null ? new String(pwdArr) : null; + } + } + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error reading input", ioe); } + } else { + throw new CommandValidationException(STRINGS.get("AdminUserRequired")); } - } else { - throw new CommandValidationException(STRINGS.get("AdminUserRequired")); + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error instantiating console", ioe); } } diff --git a/nucleus/admin/util/pom.xml b/nucleus/admin/util/pom.xml index 40806affa86..d526cc397a8 100755 --- a/nucleus/admin/util/pom.xml +++ b/nucleus/admin/util/pom.xml @@ -161,5 +161,10 @@ javax.json-api ${jsonp.version} + + jline + jline + true + diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java index 0feaeb95ab1..89fa3079e2e 100644 --- a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java @@ -43,14 +43,16 @@ import com.sun.enterprise.security.store.AsadminTruststore; import com.sun.enterprise.universal.i18n.LocalStringsImpl; -import java.io.Console; import java.io.IOException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.text.DateFormat; import java.util.Date; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.net.ssl.X509TrustManager; +import jline.console.ConsoleReader; /** * An implementation of {@link X509TrustManager} that provides basic support @@ -69,6 +71,7 @@ public class AsadminTrustManager implements X509TrustManager { private RuntimeException lastRuntimeException; private static final LocalStringsImpl STRING_MANAGER = new LocalStringsImpl(AsadminTrustManager.class); + private static final Logger logger = Logger.getLogger(AsadminTrustManager.class.getName()); /** * Creates an instance of the AsadminTrustManager @@ -162,14 +165,25 @@ public X509Certificate[] getAcceptedIssuers() { * @throws IOException * @return true if the user trusts the certificate */ - private boolean isItOKToAddCertToTrustStore(X509Certificate c) { - Console cons = System.console(); - if (!interactive || cons == null) { - return true; + private boolean isItOKToAddCertToTrustStore(X509Certificate c) { + String result = null; + + try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { + if (!interactive || cons == null) { + return true; + } + + cons.setPrompt(c.toString()); + + try { + result = cons.readLine(STRING_MANAGER.get("certificateTrustPrompt")); + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error reading input", ioe); + } + } catch (IOException ioe) { + logger.log(Level.WARNING, "Error instantiating console", ioe); } - - cons.printf("%s%n", c.toString()); - String result = cons.readLine("%s", STRING_MANAGER.get("certificateTrustPrompt")); + return result != null && result.equalsIgnoreCase("y"); } diff --git a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java index 0aa6d7a2f4e..5a47d8a0230 100644 --- a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java +++ b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java @@ -52,6 +52,7 @@ import java.util.*; import java.util.logging.Level; +import jline.console.ConsoleReader; import org.glassfish.api.Param; import org.glassfish.api.admin.*; @@ -70,7 +71,7 @@ * final protected means -- "call me but don't override me". This convention is * to make things less confusing. * If you add a method or change whether it is final -- move it to the right section. - * + * * Default instance file structure. *
      * ||---- <GlassFish Install Root>
    @@ -366,7 +367,7 @@ protected final void whackFilesystem() throws CommandException {
                 if (files != null) {
                     FileUtils.whack(whackee);
                 }
    -            
    +
                 throw new CommandException(Strings.get("DeleteInstance.noWhack", whackee));
             }
     
    @@ -493,37 +494,42 @@ protected String getNodeInstallDir() throws CommandException {
          * file with the new values.
          */
         private int updateDasPort(Properties dasprops, int port, File propfile) {
    -        Console cons;
             if (port == 8686) {     // the old JRMP port
    -            logger.info(
    -                    Strings.get("Instance.oldDasProperties",
    +            logger.info(Strings.get("Instance.oldDasProperties",
                         propfile.toString(), Integer.toString(port),
                         Integer.toString(programOpts.getPort())));
                 port = programOpts.getPort();
    -        }
    -        else if ((cons = System.console()) != null) {
    -            String line = cons.readLine("%s",
    -                    Strings.get("Instance.oldDasPropertiesPrompt",
    -                    propfile.toString(), Integer.toString(port),
    -                    Integer.toString(programOpts.getPort())));
    -            while (line != null && line.length() > 0) {
    -                try {
    -                    port = Integer.parseInt(line);
    -                    if (port > 0 && port <= 65535)
    -                        break;
    -                }catch (NumberFormatException nfex) {
    -                    //try again
    +        } else {
    +            try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) {
    +                if (cons != null) {
    +                    String line = cons.readLine(Strings.get("Instance.oldDasPropertiesPrompt",
    +                            propfile.toString(), Integer.toString(port),
    +                            Integer.toString(programOpts.getPort())));
    +                    while (line != null && line.length() > 0) {
    +                        try {
    +                            port = Integer.parseInt(line);
    +                            if (port > 0 && port <= 65535)
    +                                break;
    +                        } catch (NumberFormatException nfex) {
    +                            //try again
    +                        }
    +                        line = cons.readLine(Strings.get("Instance.reenterPort", Integer.toString(programOpts.getPort())));
    +                    }
    +                } else {
    +                    logger.info(Strings.get("Instance.oldDasPropertiesWrong",
    +                            propfile.toString(), Integer.toString(port),
    +                            Integer.toString(programOpts.getPort())));
    +                    port = programOpts.getPort();
                     }
    -                line = cons.readLine(Strings.get("Instance.reenterPort"), Integer.toString(programOpts.getPort()));
    +            } catch (IOException ioe) {
    +                logger.log(Level.WARNING, "Error reading input", ioe);
    +                logger.info(Strings.get("Instance.oldDasPropertiesWrong",
    +                        propfile.toString(), Integer.toString(port),
    +                        Integer.toString(programOpts.getPort())));
    +                port = programOpts.getPort();
                 }
             }
    -        else {
    -            logger.info(
    -                    Strings.get("Instance.oldDasPropertiesWrong",
    -                    propfile.toString(), Integer.toString(port),
    -                    Integer.toString(programOpts.getPort())));
    -            port = programOpts.getPort();
    -        }
    +
             dasprops.setProperty("agent.das.protocol", "http");
             dasprops.setProperty("agent.das.port", Integer.toString(port));
             BufferedOutputStream bos = null;
    diff --git a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupLocalDcom.java b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupLocalDcom.java
    index 7d437151d3e..678a6dbf2b5 100644
    --- a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupLocalDcom.java
    +++ b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupLocalDcom.java
    @@ -46,6 +46,8 @@
     import com.sun.enterprise.universal.process.ProcessManagerException;
     import java.io.*;
     import java.util.*;
    +
    +import jline.console.ConsoleReader;
     import org.glassfish.api.Param;
     import static com.sun.enterprise.universal.process.ProcessUtils.getExe;
     
    @@ -75,7 +77,7 @@ public final class SetupLocalDcom extends CLICommand {
         private static final String CPP_APP_FILENAME = "DcomConfigurator.exe";
         private static final File TMPDIR = new File(System.getProperty("java.io.tmpdir"));
         private static final File CPP_APP = new File(TMPDIR, CPP_APP_FILENAME);
    -    private final Console console = System.console();
    +    private ConsoleReader console;
     
         @Override
         protected void validate() throws CommandException {
    @@ -84,8 +86,19 @@ protected void validate() throws CommandException {
             if (!OS.isWindowsForSure())
                 throw new CommandException(Strings.get("vld.windows.only"));
     
    -        if (console == null)
    +        // Instantiate console if null
    +        if (console == null) {
    +            try {
    +                console = new ConsoleReader(System.in, System.out, null);
    +            } catch (IOException ioe) {
    +                logger.log(Level.WARNING, "Error instantiating console", ioe);
    +            }
    +        }
    +
    +        // Check if console is still null
    +        if (console == null) {
                 throw new CommandException(Strings.get("vld.noconsole"));
    +        }
     
             if(!force)
                 areYouSure();
    @@ -225,7 +238,13 @@ private void areYouSure() throws CommandException {
                 throw new CommandException(Strings.get("vld.not.interactive"));
     
             String msg = Strings.get("vld.areyousure");
    -        String answer = console.readLine("%s:  ", msg);
    +
    +        String answer = null;
    +        try {
    +            answer = console.readLine(msg);
    +        } catch (IOException ioe) {
    +            logger.log(Level.WARNING, "Error reading input", ioe);
    +        }
     
             if (!"yes".equalsIgnoreCase(answer))
                 throw new CommandException(Strings.get("vld.no"));
    diff --git a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java
    index cad05b42712..d55e0ecc527 100644
    --- a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java
    +++ b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java
    @@ -48,6 +48,7 @@
     import javax.inject.Inject;
     
     
    +import jline.console.ConsoleReader;
     import org.jvnet.hk2.annotations.Service;
     import org.glassfish.api.Param;
     import org.glassfish.api.admin.*;
    @@ -171,22 +172,24 @@ private boolean promptForKeyGeneration() {
             if (!programOpts.isInteractive())
                 return false;
     
    -        Console cons = System.console();
    -
    -        if (cons != null) {
    -            String val = null;
    -            do {
    -                cons.printf("%s", Strings.get("GenerateKeyPairPrompt", getRemoteUser(), Arrays.toString(hosts)));
    -                val = cons.readLine();
    -                if (val != null && (val.equalsIgnoreCase("yes") || val.equalsIgnoreCase("y"))) {
    -                    if (logger.isLoggable(Level.FINER)) {
    -                        logger.finer("Generate key!");
    +        try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) {
    +            if (cons != null) {
    +                String val = null;
    +                do {
    +                    cons.setPrompt(Strings.get("GenerateKeyPairPrompt", getRemoteUser(), Arrays.toString(hosts)));
    +                    val = cons.readLine();
    +                    if (val != null && (val.equalsIgnoreCase("yes") || val.equalsIgnoreCase("y"))) {
    +                        if (logger.isLoggable(Level.FINER)) {
    +                            logger.finer("Generate key!");
    +                        }
    +                        return true;
    +                    } else if (val != null && (val.equalsIgnoreCase("no") || val.equalsIgnoreCase("n"))) {
    +                        break;
                         }
    -                    return true;
    -                } else if (val != null && (val.equalsIgnoreCase("no") || val.equalsIgnoreCase("n"))) {
    -                    break;
    -                }
    -            } while (val != null && !isValidAnswer(val));
    +                } while (val != null && !isValidAnswer(val));
    +            }
    +        } catch (IOException ioe) {
    +            logger.log(Level.WARNING, "Error reading input", ioe);
             }
             return false;
         }
    diff --git a/nucleus/common/common-util/pom.xml b/nucleus/common/common-util/pom.xml
    index 137397e193c..876bf61a920 100755
    --- a/nucleus/common/common-util/pom.xml
    +++ b/nucleus/common/common-util/pom.xml
    @@ -122,5 +122,10 @@
                 org.osgi.enterprise
                 provided
             
    +        
    +            jline
    +            jline
    +            true
    +        
         
     
    diff --git a/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java b/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java
    index 6c525c58890..48e91fb6341 100644
    --- a/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java
    +++ b/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java
    @@ -41,7 +41,6 @@
     package com.sun.enterprise.security.store;
     
     import java.io.BufferedInputStream;
    -import java.io.Console;
     import java.io.File;
     import java.io.FileInputStream;
     import java.io.FileNotFoundException;
    @@ -55,6 +54,8 @@
     import java.util.logging.Level;
     import java.util.logging.Logger;
     
    +import jline.console.ConsoleReader;
    +
     import com.sun.enterprise.universal.i18n.LocalStringsImpl;
     import com.sun.enterprise.util.CULoggerInfo;
     import com.sun.enterprise.util.SystemPropertyConstants;
    @@ -173,10 +174,19 @@ private AsadminSecurityUtil(final char[] commandLineMasterPassword, final boolea
          * @return the password to the client side truststore
          */
         private char[] promptForPassword() throws IOException {
    -        Console cons = System.console();
    -        if (cons != null) {
    -            return cons.readPassword(strmgr.get("certificateDbPrompt"));
    +        try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) {
    +            if (cons != null) {
    +                // Don't echo anything when reading
    +                char echoCharacter = 0;
    +                cons.setEchoCharacter(echoCharacter);
    +
    +                String line = cons.readLine(strmgr.get("certificateDbPrompt"));
    +                return line.toCharArray();
    +            }
    +        } catch (IOException ioe) {
    +            logger.log(Level.WARNING, "Error reading input", ioe);
             }
    +
             return null;
         }
     
    
    From c9c78c88fcf8bae3bf432f58e864c154c2813f4a Mon Sep 17 00:00:00 2001
    From: Jan Bernitt 
    Date: Thu, 28 Mar 2019 10:25:43 +0100
    Subject: [PATCH 084/108] PAYARA-3466 added missing copyright headers
    
    ---
     .../impl/model/util/AnnotationInfo.java       | 39 +++++++++++++++++++
     .../app/application/HelloControllerTest.java  | 39 +++++++++++++++++++
     .../test/app/application/HiddenTest.java      | 39 +++++++++++++++++++
     .../test/app/application/RootPathTest.java    |  2 +-
     .../openapi/test/app/data/TestComponent.java  |  2 +-
     5 files changed, 119 insertions(+), 2 deletions(-)
    
    diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java
    index 5839c4975e0..1ce7ed8312e 100644
    --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java
    +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java
    @@ -1,3 +1,42 @@
    +/*
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    + *
    + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved.
    + *
    + * The contents of this file are subject to the terms of either the GNU
    + * General Public License Version 2 only ("GPL") or the Common Development
    + * and Distribution License("CDDL") (collectively, the "License").  You
    + * may not use this file except in compliance with the License.  You can
    + * obtain a copy of the License at
    + * https://github.com/payara/Payara/blob/master/LICENSE.txt
    + * See the License for the specific
    + * language governing permissions and limitations under the License.
    + *
    + * When distributing the software, include this License Header Notice in each
    + * file and include the License file at glassfish/legal/LICENSE.txt.
    + *
    + * GPL Classpath Exception:
    + * The Payara Foundation designates this particular file as subject to the "Classpath"
    + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
    + * file that accompanied this code.
    + *
    + * Modifications:
    + * If applicable, add the following below the License Header, with the fields
    + * enclosed by brackets [] replaced by your own identifying information:
    + * "Portions Copyright [year] [name of copyright owner]"
    + *
    + * Contributor(s):
    + * If you wish your version of this file to be governed by only the CDDL or
    + * only the GPL Version 2, indicate your decision by adding "[Contributor]
    + * elects to include this software in this distribution under the [CDDL or GPL
    + * Version 2] license."  If you don't indicate a single choice of license, a
    + * recipient has the option to distribute your version of this file under
    + * either the CDDL, the GPL Version 2 or to extend the choice of license to
    + * its licensees as provided above.  However, if you add GPL Version 2 code
    + * and therefore, elected the GPL Version 2 license, then the option applies
    + * only if the new code is made subject to such option by the copyright
    + * holder.
    + */
     package fish.payara.microprofile.openapi.impl.model.util;
     
     import java.lang.annotation.Annotation;
    diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HelloControllerTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HelloControllerTest.java
    index 3f60c8b473d..0ee260ad3ba 100644
    --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HelloControllerTest.java
    +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HelloControllerTest.java
    @@ -1,3 +1,42 @@
    +/*
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    + *
    + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved.
    + *
    + * The contents of this file are subject to the terms of either the GNU
    + * General Public License Version 2 only ("GPL") or the Common Development
    + * and Distribution License("CDDL") (collectively, the "License").  You
    + * may not use this file except in compliance with the License.  You can
    + * obtain a copy of the License at
    + * https://github.com/payara/Payara/blob/master/LICENSE.txt
    + * See the License for the specific
    + * language governing permissions and limitations under the License.
    + *
    + * When distributing the software, include this License Header Notice in each
    + * file and include the License file at glassfish/legal/LICENSE.txt.
    + *
    + * GPL Classpath Exception:
    + * The Payara Foundation designates this particular file as subject to the "Classpath"
    + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
    + * file that accompanied this code.
    + *
    + * Modifications:
    + * If applicable, add the following below the License Header, with the fields
    + * enclosed by brackets [] replaced by your own identifying information:
    + * "Portions Copyright [year] [name of copyright owner]"
    + *
    + * Contributor(s):
    + * If you wish your version of this file to be governed by only the CDDL or
    + * only the GPL Version 2, indicate your decision by adding "[Contributor]
    + * elects to include this software in this distribution under the [CDDL or GPL
    + * Version 2] license."  If you don't indicate a single choice of license, a
    + * recipient has the option to distribute your version of this file under
    + * either the CDDL, the GPL Version 2 or to extend the choice of license to
    + * its licensees as provided above.  However, if you add GPL Version 2 code
    + * and therefore, elected the GPL Version 2 license, then the option applies
    + * only if the new code is made subject to such option by the copyright
    + * holder.
    + */
     package fish.payara.microprofile.openapi.test.app.application;
     
     import static fish.payara.microprofile.openapi.test.util.JsonUtils.path;
    diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HiddenTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HiddenTest.java
    index 6ef25162f3b..48731fe4d1c 100644
    --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HiddenTest.java
    +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/HiddenTest.java
    @@ -1,3 +1,42 @@
    +/*
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    + *
    + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved.
    + *
    + * The contents of this file are subject to the terms of either the GNU
    + * General Public License Version 2 only ("GPL") or the Common Development
    + * and Distribution License("CDDL") (collectively, the "License").  You
    + * may not use this file except in compliance with the License.  You can
    + * obtain a copy of the License at
    + * https://github.com/payara/Payara/blob/master/LICENSE.txt
    + * See the License for the specific
    + * language governing permissions and limitations under the License.
    + *
    + * When distributing the software, include this License Header Notice in each
    + * file and include the License file at glassfish/legal/LICENSE.txt.
    + *
    + * GPL Classpath Exception:
    + * The Payara Foundation designates this particular file as subject to the "Classpath"
    + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
    + * file that accompanied this code.
    + *
    + * Modifications:
    + * If applicable, add the following below the License Header, with the fields
    + * enclosed by brackets [] replaced by your own identifying information:
    + * "Portions Copyright [year] [name of copyright owner]"
    + *
    + * Contributor(s):
    + * If you wish your version of this file to be governed by only the CDDL or
    + * only the GPL Version 2, indicate your decision by adding "[Contributor]
    + * elects to include this software in this distribution under the [CDDL or GPL
    + * Version 2] license."  If you don't indicate a single choice of license, a
    + * recipient has the option to distribute your version of this file under
    + * either the CDDL, the GPL Version 2 or to extend the choice of license to
    + * its licensees as provided above.  However, if you add GPL Version 2 code
    + * and therefore, elected the GPL Version 2 license, then the option applies
    + * only if the new code is made subject to such option by the copyright
    + * holder.
    + */
     package fish.payara.microprofile.openapi.test.app.application;
     
     import static fish.payara.microprofile.openapi.test.util.JsonUtils.path;
    diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java
    index c4eb8cc04b2..6c3bf67f069 100644
    --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java
    +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/RootPathTest.java
    @@ -66,4 +66,4 @@ public void testRoot() {
             assertEquals("The root resource had the wrong origin.", "getRoot",
                     getDocument().getPaths().getPathItem("/test").getGET().getOperationId());
         }
    -}
    \ No newline at end of file
    +}
    diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java
    index 171aecbd1d4..e279003d272 100644
    --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java
    +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/data/TestComponent.java
    @@ -59,4 +59,4 @@ public void pojoCreationTest() {
             assertNotNull(getDocument().getComponents().getSchemas().get("TestComponent"));
         }
     
    -}
    \ No newline at end of file
    +}
    
    From acb3409f2ce39ceae9d227bdfc0c434e99820782 Mon Sep 17 00:00:00 2001
    From: Cuba 
    Date: Thu, 28 Mar 2019 04:55:39 -0700
    Subject: [PATCH 085/108] removed duplicate classes
    
    ---
     .../rest/admin/DisableEjbInvokerCommand.java  | 129 -----------------
     .../rest/admin/EnableEjbInvokerCommand.java   | 130 ------------------
     2 files changed, 259 deletions(-)
     delete mode 100644 appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java
     delete mode 100644 appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java
    
    diff --git a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java
    deleted file mode 100644
    index ffea8c0acf7..00000000000
    --- a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/DisableEjbInvokerCommand.java
    +++ /dev/null
    @@ -1,129 +0,0 @@
    -/*
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    - *
    - * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved.
    - *
    - * The contents of this file are subject to the terms of either the GNU
    - * General Public License Version 2 only ("GPL") or the Common Development
    - * and Distribution License("CDDL") (collectively, the "License").  You
    - * may not use this file except in compliance with the License.  You can
    - * obtain a copy of the License at
    - * https://github.com/payara/Payara/blob/master/LICENSE.txt
    - * See the License for the specific
    - * language governing permissions and limitations under the License.
    - *
    - * When distributing the software, include this License Header Notice in each
    - * file and include the License file at glassfish/legal/LICENSE.txt.
    - *
    - * GPL Classpath Exception:
    - * The Payara Foundation designates this particular file as subject to the "Classpath"
    - * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
    - * file that accompanied this code.
    - *
    - * Modifications:
    - * If applicable, add the following below the License Header, with the fields
    - * enclosed by brackets [] replaced by your own identifying information:
    - * "Portions Copyright [year] [name of copyright owner]"
    - *
    - * Contributor(s):
    - * If you wish your version of this file to be governed by only the CDDL or
    - * only the GPL Version 2, indicate your decision by adding "[Contributor]
    - * elects to include this software in this distribution under the [CDDL or GPL
    - * Version 2] license."  If you don't indicate a single choice of license, a
    - * recipient has the option to distribute your version of this file under
    - * either the CDDL, the GPL Version 2 or to extend the choice of license to
    - * its licensees as provided above.  However, if you add GPL Version 2 code
    - * and therefore, elected the GPL Version 2 license, then the option applies
    - * only if the new code is made subject to such option by the copyright
    - * holder.
    - */
    -package fish.payara.ejb.rest.admin;
    -
    -import static org.glassfish.config.support.CommandTarget.CLUSTER;
    -import static org.glassfish.config.support.CommandTarget.CLUSTERED_INSTANCE;
    -import static org.glassfish.config.support.CommandTarget.CONFIG;
    -import static org.glassfish.config.support.CommandTarget.DAS;
    -import static org.glassfish.config.support.CommandTarget.DEPLOYMENT_GROUP;
    -import static org.glassfish.config.support.CommandTarget.STANDALONE_INSTANCE;
    -import static org.glassfish.deployment.autodeploy.AutoDeployer.getNameFromFilePath;
    -
    -import java.nio.file.Path;
    -
    -import javax.inject.Inject;
    -
    -import com.sun.enterprise.config.serverbeans.Domain;
    -import org.glassfish.api.ActionReport;
    -import org.glassfish.api.Param;
    -import org.glassfish.api.admin.AdminCommand;
    -import org.glassfish.api.admin.AdminCommandContext;
    -import org.glassfish.api.admin.ExecuteOn;
    -import org.glassfish.api.admin.RuntimeType;
    -import org.glassfish.api.admin.ServerEnvironment;
    -import org.glassfish.config.support.TargetType;
    -import org.glassfish.deployment.autodeploy.AutoDeployer.AutodeploymentStatus;
    -import org.glassfish.deployment.autodeploy.AutoUndeploymentOperation;
    -import org.glassfish.hk2.api.PerLookup;
    -import org.glassfish.hk2.api.ServiceLocator;
    -import org.jvnet.hk2.annotations.Service;
    -
    -/**
    - * This command disables the EJB invoker endpoint.
    - * 
    - * 

    - * This happens by undeploying the small application in /domains/[domain]/endpoints/ejb-invoker. - * Note that by default this application is not deployed. The default context root of this application is - * /ejb-invoker, but it may have been set to a different root by the {@link EnableEjbInvokerCommand} - * command. - * - * @author Arjan Tijms - * - */ -@Deprecated -@Service(name = "disable-ejb-invoker") -@PerLookup -@ExecuteOn(RuntimeType.DAS) -@TargetType({ DAS, STANDALONE_INSTANCE, CLUSTER, CLUSTERED_INSTANCE, CONFIG, DEPLOYMENT_GROUP }) -public class DisableEjbInvokerCommand implements AdminCommand { - - private final String ENDPOINTS = "endpoints"; - private final String EJB_INVOKER = "ejb-invoker"; - - @Param(optional = true) - public String target; - - @Inject - private ServerEnvironment serverEnvironment; - - @Inject - private ServiceLocator serviceLocator; - - @Inject - private Domain domain; - - @Override - public void execute(AdminCommandContext context) { - - Path endPointsPath = serverEnvironment.getInstanceRoot().toPath().resolve(ENDPOINTS); - Path ejbInvokerPath = endPointsPath.resolve(EJB_INVOKER); - - AutoUndeploymentOperation autoUndeploymentOperation = AutoUndeploymentOperation.newInstance( - serviceLocator, - ejbInvokerPath.toFile(), - getNameFromFilePath(endPointsPath.toFile(), ejbInvokerPath.toFile()), - target); - - AutodeploymentStatus deploymentStatus = autoUndeploymentOperation.run(); - - ActionReport report = context.getActionReport(); - report.setActionExitCode(deploymentStatus.getExitCode()); - - if (deploymentStatus.getExitCode().equals(ActionReport.ExitCode.FAILURE)) { - if (domain.getApplications().getApplication("ejb-invoker") == null) { - report.appendMessage("\nEJB Invoker is not enabled on any target"); - } else { - report.appendMessage("\nFailed to disable Ejb Invoker - was it enabled on the specified target?"); - } - } - } - -} diff --git a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java b/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java deleted file mode 100644 index a23e1f687f6..00000000000 --- a/appserver/ejb/ejb-http-remoting/admin/src/main/java/fish/payara/ejb/rest/admin/EnableEjbInvokerCommand.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can - * obtain a copy of the License at - * https://github.com/payara/Payara/blob/master/LICENSE.txt - * See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at glassfish/legal/LICENSE.txt. - * - * GPL Classpath Exception: - * The Payara Foundation designates this particular file as subject to the "Classpath" - * exception as provided by the Payara Foundation in the GPL Version 2 section of the License - * file that accompanied this code. - * - * Modifications: - * If applicable, add the following below the License Header, with the fields - * enclosed by brackets [] replaced by your own identifying information: - * "Portions Copyright [year] [name of copyright owner]" - * - * Contributor(s): - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ -package fish.payara.ejb.rest.admin; - -import static org.glassfish.config.support.CommandTarget.CLUSTER; -import static org.glassfish.config.support.CommandTarget.CLUSTERED_INSTANCE; -import static org.glassfish.config.support.CommandTarget.CONFIG; -import static org.glassfish.config.support.CommandTarget.DAS; -import static org.glassfish.config.support.CommandTarget.DEPLOYMENT_GROUP; -import static org.glassfish.config.support.CommandTarget.STANDALONE_INSTANCE; - -import javax.inject.Inject; - -import com.sun.enterprise.config.serverbeans.Domain; -import org.glassfish.api.ActionReport; -import org.glassfish.api.Param; -import org.glassfish.api.admin.AdminCommand; -import org.glassfish.api.admin.AdminCommandContext; -import org.glassfish.api.admin.ExecuteOn; -import org.glassfish.api.admin.RuntimeType; -import org.glassfish.api.admin.ServerEnvironment; -import org.glassfish.config.support.TargetType; -import org.glassfish.deployment.autodeploy.AutoDeployer.AutodeploymentStatus; -import org.glassfish.deployment.autodeploy.AutoDeploymentOperation; -import org.glassfish.hk2.api.PerLookup; -import org.glassfish.hk2.api.ServiceLocator; -import org.jvnet.hk2.annotations.Service; - -/** - * This command enables the EJB invoker endpoint and optionally allows it to set an - * alternative context root. - * - *

    - * This happens by the deploying a small application in /domains/[domain]/endpoints/ejb-invoker - * which by default is not deployed. The default context root of this application is - * /ejb-invoker. - * - * @author Arjan Tijms - * - */ -@Deprecated -@Service(name = "enable-ejb-invoker") -@PerLookup -@ExecuteOn(RuntimeType.DAS) -@TargetType({ DAS, STANDALONE_INSTANCE, CLUSTER, CLUSTERED_INSTANCE, CONFIG, DEPLOYMENT_GROUP }) -public class EnableEjbInvokerCommand implements AdminCommand { - - private final String ENDPOINT = "endpoints/ejb-invoker"; - - @Param(name = "contextRoot", primary = true, optional = true) - private String contextRoot; - - @Param(optional = true) - public String target; - - @Inject - private ServerEnvironment serverEnvironment; - - @Inject - private ServiceLocator serviceLocator; - - @Inject - private Domain domain; - - @Override - public void execute(AdminCommandContext context) { - AutoDeploymentOperation autoDeploymentOperation = AutoDeploymentOperation.newInstance( - serviceLocator, - serverEnvironment.getInstanceRoot().toPath().resolve(ENDPOINT).toFile(), - getDefaultVirtualServer(), - target, - contextRoot - ); - - if (domain.getApplications().getApplication("ejb-invoker") == null) { - AutodeploymentStatus deploymentStatus = autoDeploymentOperation.run(); - ActionReport report = context.getActionReport(); - report.setActionExitCode(deploymentStatus.getExitCode()); - } else { - ActionReport report = context.getActionReport(); - report.setActionExitCode(ActionReport.ExitCode.WARNING); - report.setMessage("EJB Invoker is already deployed on at least one target, please edit it as you would a " + - "normal application using the create-application-ref, delete-application-ref, " + - "or update-application-ref commands"); - } - } - - private String getDefaultVirtualServer() { - // XXX write this? - return null; - } - -} From aa4302d6af6a74bb7ec47b64bc7f29ea9b671833 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Thu, 28 Mar 2019 13:47:59 +0100 Subject: [PATCH 086/108] PAYARA-3468 pre-work cleanup of warnings, mostly genercis, unnecessary else --- .../faulttolerance/FaultToleranceService.java | 16 ++-- .../FaultToleranceServiceConfiguration.java | 3 +- .../cdi/FaultToleranceCDIExtension.java | 2 +- .../cdi/FaultToleranceCdiUtils.java | 44 +++++---- .../interceptors/AsynchronousInterceptor.java | 18 ++-- .../interceptors/BulkheadInterceptor.java | 61 +++++++------ .../CircuitBreakerInterceptor.java | 90 +++++++++---------- .../interceptors/RetryInterceptor.java | 84 +++++++++-------- .../interceptors/TimeoutInterceptor.java | 53 ++++++----- .../interceptors/fallback/FallbackPolicy.java | 15 ++-- .../validators/BulkheadValidator.java | 4 +- .../validators/CircuitBreakerValidator.java | 8 +- .../validators/FallbackValidator.java | 28 +++--- .../validators/RetryValidator.java | 8 +- .../validators/TimeoutValidator.java | 2 +- 15 files changed, 211 insertions(+), 225 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/FaultToleranceService.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/FaultToleranceService.java index 028133a1b0a..bfebb1e62b4 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/FaultToleranceService.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/FaultToleranceService.java @@ -116,7 +116,7 @@ public void postConstruct() { } @Override - public void event(Event event) { + public void event(Event event) { if (event.is(Deployment.APPLICATION_UNLOADED)) { ApplicationInfo info = (ApplicationInfo) event.hook(); deregisterApplication(info.getName()); @@ -135,10 +135,9 @@ public Boolean isFaultToleranceEnabled(String applicationName, Config config) { try { if (faultToleranceObjects.containsKey(applicationName)) { return faultToleranceObjects.get(applicationName).isEnabled(); - } else { - initialiseFaultToleranceObject(applicationName, config); - return faultToleranceObjects.get(applicationName).isEnabled(); } + initialiseFaultToleranceObject(applicationName, config); + return faultToleranceObjects.get(applicationName).isEnabled(); } catch (NullPointerException npe) { initialiseFaultToleranceObject(applicationName, config); return faultToleranceObjects.get(applicationName).isEnabled(); @@ -156,10 +155,9 @@ public Boolean isFaultToleranceEnabled(String applicationName, Config config) { public Boolean areFaultToleranceMetricsEnabled(String applicationName, Config config) { if (faultToleranceObjects.containsKey(applicationName)) { return faultToleranceObjects.get(applicationName).areMetricsEnabled(); - } else { - initialiseFaultToleranceObject(applicationName, config); - return faultToleranceObjects.get(applicationName).areMetricsEnabled(); } + initialiseFaultToleranceObject(applicationName, config); + return faultToleranceObjects.get(applicationName).areMetricsEnabled(); } /** @@ -526,7 +524,7 @@ public String getApplicationName(InvocationManager invocationManager, Invocation * @param annotatedMethod The annotated Method to generate the signature for * @return A String in the format of CanonicalClassName#MethodName({ParameterTypes})>ReturnType */ - private String getFullMethodSignature(Method annotatedMethod) { + private static String getFullMethodSignature(Method annotatedMethod) { return annotatedMethod.getDeclaringClass().getCanonicalName() + "#" + annotatedMethod.getName() + "(" + Arrays.toString(annotatedMethod.getParameterTypes()) + ")" @@ -547,7 +545,7 @@ public void endFaultToleranceSpan() { } } - private void addGenericFaultToleranceRequestTracingDetails(RequestTraceSpan span, + private static void addGenericFaultToleranceRequestTracingDetails(RequestTraceSpan span, InvocationManager invocationManager, InvocationContext invocationContext) { span.addSpanTag("App Name", invocationManager.getCurrentInvocation().getAppName()); span.addSpanTag("Component ID", invocationManager.getCurrentInvocation().getComponentId()); diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/FaultToleranceServiceConfiguration.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/FaultToleranceServiceConfiguration.java index 95ae59c9f6d..1af9ec7bdff 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/FaultToleranceServiceConfiguration.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/FaultToleranceServiceConfiguration.java @@ -41,7 +41,6 @@ import org.glassfish.api.admin.config.ConfigExtension; import org.jvnet.hk2.config.Attribute; -import org.jvnet.hk2.config.ConfigBeanProxy; import org.jvnet.hk2.config.Configured; /** @@ -49,7 +48,7 @@ * @author Andrew Pielage */ @Configured(name = "microprofile-fault-tolerance-configuration") -public interface FaultToleranceServiceConfiguration extends ConfigBeanProxy, ConfigExtension { +public interface FaultToleranceServiceConfiguration extends ConfigExtension { @Attribute(defaultValue = "concurrent/__defaultManagedExecutorService", dataType = String.class) public String getManagedExecutorService(); diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/cdi/FaultToleranceCDIExtension.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/cdi/FaultToleranceCDIExtension.java index f8c2ed09710..10c680470f5 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/cdi/FaultToleranceCDIExtension.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/cdi/FaultToleranceCDIExtension.java @@ -119,7 +119,7 @@ void processAnnotatedType(@Observes @WithAnnotations({ Asynchronous.class, B * @param annotatedMethod The annotated method to validate * @throws Exception */ - private void validateMethodAnnotations(AnnotatedMethod annotatedMethod) + private static void validateMethodAnnotations(AnnotatedMethod annotatedMethod) throws ClassNotFoundException, NoSuchMethodException { Config config = ConfigProvider.getConfig(); diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/cdi/FaultToleranceCdiUtils.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/cdi/FaultToleranceCdiUtils.java index 48a593b7779..1b58a0eaa76 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/cdi/FaultToleranceCdiUtils.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/cdi/FaultToleranceCdiUtils.java @@ -117,9 +117,9 @@ public static A getAnnotation(BeanManager beanManager, Cl * @param parameterType The type of the parameter to get the override value of * @return */ - public static Optional getOverrideValue(Config config, Class annotationClass, - String parameterName, String annotatedMethodName, String annotatedClassCanonicalName, Class parameterType) { - Optional value = Optional.empty(); + public static Optional getOverrideValue(Config config, Class annotationClass, + String parameterName, String annotatedMethodName, String annotatedClassCanonicalName, Class parameterType) { + Optional value = Optional.empty(); String annotationName = annotationClass.getSimpleName(); @@ -164,9 +164,9 @@ public static Optional getOverrideValue(Config config, Cl * @param parameterType The type of the parameter to get the override value of * @return */ - public static Optional getOverrideValue(Config config, Class annotationClass, - String parameterName, InvocationContext invocationContext, Class parameterType) { - Optional value = Optional.empty(); + public static Optional getOverrideValue(Config config, Class annotationClass, + String parameterName, InvocationContext invocationContext, Class parameterType) { + Optional value = Optional.empty(); // Get the annotation, method, and class names String annotationName = annotationClass.getSimpleName(); @@ -220,9 +220,9 @@ public static Optional getOverrideValue(Config config, Cl * @param invocationContext The context of the invoking request * @return */ - public static Optional getEnabledOverrideValue(Config config, Class annotationClass, + public static Optional getEnabledOverrideValue(Config config, Class annotationClass, InvocationContext invocationContext) { - Optional value = Optional.empty(); + Optional value = Optional.empty(); // Get the annotation, method, and class names String annotationName = annotationClass.getSimpleName(); @@ -270,7 +270,7 @@ public static Optional getEnabledOverrideValue(Config con * @param value The Optional value to check if an override was found for * @param level A String denoting the level of override you were checking for */ - private static void logOverride(Optional value, String level) { + private static void logOverride(Optional value, String level) { if (value.isPresent()) { logger.log(Level.FINER, "{0} override found.", level); } else { @@ -286,9 +286,9 @@ private static void logOverride(Optional value, String level) { * @param config The config to get the overriding enabled value from * @return An overriding enabled value if there is one */ - private static Optional checkAnnotatedMethodForEnabledOverride(String annotatedClassCanonicalName, + private static Optional checkAnnotatedMethodForEnabledOverride(String annotatedClassCanonicalName, String annotationName, Config config) { - Optional value = checkForClassLevelOverride(annotatedClassCanonicalName, annotationName, "enabled", + Optional value = checkForClassLevelOverride(annotatedClassCanonicalName, annotationName, "enabled", Boolean.class, config); if (!value.isPresent()) { @@ -307,11 +307,11 @@ private static Optional checkAnnotatedMethodForEnabledOverride(String annotatedC * @param config The config to get the overriding value from * @return An overriding value for the provided parameter if there is one */ - private static Optional checkForClassLevelOverride(String annotatedClassCanonicalName, String annotationName, - String parameterName, Class parameterType, Config config) { + private static Optional checkForClassLevelOverride(String annotatedClassCanonicalName, String annotationName, + String parameterName, Class parameterType, Config config) { logger.log(Level.FINER, "No config override for annotated method, getting config override for the " + "annotated class..."); - Optional value = config.getOptionalValue(annotatedClassCanonicalName + "/" + annotationName + Optional value = config.getOptionalValue(annotatedClassCanonicalName + "/" + annotationName + "/" + parameterName, parameterType); logOverride(value, "Class-level"); @@ -326,10 +326,10 @@ private static Optional checkForClassLevelOverride(String annotatedClassCanonica * @param config The config to get the overriding value from * @return */ - private static Optional checkForGlobalLevelOverride(String annotationName, String parameterName, Class parameterType, + private static Optional checkForGlobalLevelOverride(String annotationName, String parameterName, Class parameterType, Config config) { logger.log(Level.FINER, "No config override for annotated class, checking for global override."); - Optional value = config.getOptionalValue(annotationName + "/" + parameterName, parameterType); + Optional value = config.getOptionalValue(annotationName + "/" + parameterName, parameterType); logOverride(value, "Global"); return value; @@ -343,15 +343,14 @@ private static Optional checkForGlobalLevelOverride(String annotationName, Strin * @param annotationClass The class of the annotation * @return The class of the annotated method */ - public static Class getAnnotatedMethodClass(InvocationContext invocationContext, + public static Class getAnnotatedMethodClass(InvocationContext invocationContext, Class annotationClass) { - Class targetClass = invocationContext.getTarget().getClass(); + Class targetClass = invocationContext.getTarget().getClass(); if (targetClass.isAnnotationPresent(annotationClass)) { return targetClass; - } else { - return invocationContext.getMethod().getDeclaringClass(); } + return invocationContext.getMethod().getDeclaringClass(); } /** @@ -361,16 +360,15 @@ public static Class getAnnotatedMethodClass(InvocationCon * @param annotatedClass The class of the annotation * @return The canonical name of the annotated method's class */ - public static String getAnnotatedMethodClassCanonicalName(Class annotatedClass) { + public static String getAnnotatedMethodClassCanonicalName(Class annotatedClass) { String canonicalClassName = annotatedClass.getCanonicalName(); // If the class was a proxy from Weld, cut away the appended gubbins // Author Note: There's probably a better way of doing this... if (canonicalClassName.contains("$Proxy$_$$_WeldSubclass")) { return canonicalClassName.split("\\$Proxy\\$_\\$\\$_WeldSubclass")[0]; - } else { - return canonicalClassName; } + return canonicalClassName; } /** diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/AsynchronousInterceptor.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/AsynchronousInterceptor.java index 5737f1716bb..3726105af01 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/AsynchronousInterceptor.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/AsynchronousInterceptor.java @@ -105,12 +105,10 @@ public Object intercept(InvocationContext invocationContext) throws Exception { // Attempt to proceed the InvocationContext with Asynchronous semantics if Fault Tolerance is enabled for // this method if (faultToleranceService.isFaultToleranceEnabled(appName, config) - && ((Boolean) FaultToleranceCdiUtils.getEnabledOverrideValue( + && (FaultToleranceCdiUtils.getEnabledOverrideValue( config, Asynchronous.class, invocationContext) .orElse(Boolean.TRUE))) { - Callable callable = () -> { - return invocationContext.proceed(); - }; + Callable callable = () -> invocationContext.proceed(); logger.log(Level.FINER, "Proceeding invocation asynchronously"); proceededInvocationContext = new FutureDelegator(managedExecutorService.submit(callable)); } else { @@ -126,7 +124,7 @@ public Object intercept(InvocationContext invocationContext) throws Exception { // If the method was annotated with Fallback and the annotation is enabled, attempt it, otherwise just // propagate the exception upwards - if (fallback != null && ((Boolean) FaultToleranceCdiUtils.getEnabledOverrideValue( + if (fallback != null && (FaultToleranceCdiUtils.getEnabledOverrideValue( config, Fallback.class, invocationContext) .orElse(Boolean.TRUE))) { logger.log(Level.FINE, "Fallback annotation found on method - falling back from Asynchronous"); @@ -175,15 +173,14 @@ public Object get() throws InterruptedException, ExecutionException { // If the result of future.get() is still a future, get it again if (proceededInvocation instanceof Future) { - Future tempFuture = (Future) proceededInvocation; + Future tempFuture = (Future) proceededInvocation; proceededInvocation = tempFuture.get(); } } catch (InterruptedException | ExecutionException ex) { if (ex.getCause() instanceof FaultToleranceException) { throw (FaultToleranceException) ex.getCause(); - } else { - throw ex; } + throw ex; } return proceededInvocation; @@ -198,15 +195,14 @@ public Object get(long timeout, TimeUnit unit) throws InterruptedException, Exec // If the result of future.get() is still a future, get it again if (proceededInvocation instanceof Future) { - Future tempFuture = (Future) proceededInvocation; + Future tempFuture = (Future) proceededInvocation; proceededInvocation = tempFuture.get(timeout, unit); } } catch (InterruptedException | ExecutionException | TimeoutException ex) { if (ex.getCause() instanceof FaultToleranceException) { throw new ExecutionException(ex.getCause()); - } else { - throw ex; } + throw ex; } return proceededInvocation; diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/BulkheadInterceptor.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/BulkheadInterceptor.java index 8dbf4c03631..8ff6c73bdae 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/BulkheadInterceptor.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/BulkheadInterceptor.java @@ -110,7 +110,7 @@ public Object intercept(InvocationContext invocationContext) throws Exception { // Attempt to proceed the InvocationContext with Asynchronous semantics if Fault Tolerance is enabled for this // method if (faultToleranceService.isFaultToleranceEnabled(appName, config) - && ((Boolean) FaultToleranceCdiUtils.getEnabledOverrideValue( + && (FaultToleranceCdiUtils.getEnabledOverrideValue( config, Bulkhead.class, invocationContext) .orElse(Boolean.TRUE))) { if (faultToleranceService.areFaultToleranceMetricsEnabled(appName, config)) { @@ -136,31 +136,30 @@ public Object intercept(InvocationContext invocationContext) throws Exception { if (retry != null) { logger.log(Level.FINE, "Retry annotation found on method, propagating error upwards."); throw ex; - } else { - // If an exception was thrown, check if the method is annotated with @Fallback - Fallback fallback = FaultToleranceCdiUtils.getAnnotation(beanManager, Fallback.class, - invocationContext); + } + // If an exception was thrown, check if the method is annotated with @Fallback + Fallback fallback = FaultToleranceCdiUtils.getAnnotation(beanManager, Fallback.class, + invocationContext); - // If the method was annotated with Fallback and the annotation is enabled, attempt it, otherwise just - // propagate the exception upwards - if (fallback != null && ((Boolean) FaultToleranceCdiUtils.getEnabledOverrideValue( - config, Fallback.class, invocationContext) - .orElse(Boolean.TRUE))) { - logger.log(Level.FINE, "Fallback annotation found on method, and no Retry annotation - " - + "falling back from Bulkhead"); - FallbackPolicy fallbackPolicy = new FallbackPolicy(fallback, config, invocationContext); - proceededInvocationContext = fallbackPolicy.fallback(invocationContext, ex); - } else { - logger.log(Level.FINE, "Fallback annotation not found on method, propagating error upwards.", ex); - - // Increment the failure counter metric - faultToleranceService.incrementCounterMetric(metricRegistry, - "ft." + fullMethodSignature + ".invocations.failed.total", - faultToleranceService.getApplicationName(invocationManager, invocationContext), - config); - - throw ex; - } + // If the method was annotated with Fallback and the annotation is enabled, attempt it, otherwise just + // propagate the exception upwards + if (fallback != null && (FaultToleranceCdiUtils.getEnabledOverrideValue( + config, Fallback.class, invocationContext) + .orElse(Boolean.TRUE))) { + logger.log(Level.FINE, "Fallback annotation found on method, and no Retry annotation - " + + "falling back from Bulkhead"); + FallbackPolicy fallbackPolicy = new FallbackPolicy(fallback, config, invocationContext); + proceededInvocationContext = fallbackPolicy.fallback(invocationContext, ex); + } else { + logger.log(Level.FINE, "Fallback annotation not found on method, propagating error upwards.", ex); + + // Increment the failure counter metric + faultToleranceService.incrementCounterMetric(metricRegistry, + "ft." + fullMethodSignature + ".invocations.failed.total", + faultToleranceService.getApplicationName(invocationManager, invocationContext), + config); + + throw ex; } } @@ -188,10 +187,10 @@ private Object bulkhead(InvocationContext invocationContext) throws Exception { logger.log(Level.INFO, "No config could be found", ex); } - int value = (Integer) FaultToleranceCdiUtils.getOverrideValue( + int value = FaultToleranceCdiUtils.getOverrideValue( config, Bulkhead.class, "value", invocationContext, Integer.class) .orElse(bulkhead.value()); - int waitingTaskQueue = (Integer) FaultToleranceCdiUtils.getOverrideValue( + int waitingTaskQueue = FaultToleranceCdiUtils.getOverrideValue( config, Bulkhead.class, "waitingTaskQueue", invocationContext, Integer.class) .orElse(bulkhead.waitingTaskQueue()); @@ -209,7 +208,7 @@ private Object bulkhead(InvocationContext invocationContext) throws Exception { invocationContext.getTarget(), invocationContext.getMethod(), value); if (faultToleranceService.areFaultToleranceMetricsEnabled(appName, config)) { - Gauge concurrentExecutionsGauge = metricRegistry.getGauges() + Gauge concurrentExecutionsGauge = metricRegistry.getGauges() .get("ft." + fullMethodSignature + ".bulkhead.concurrentExecutions"); // Register a bulkhead concurrent executions metric if there isn't one @@ -227,7 +226,7 @@ private Object bulkhead(InvocationContext invocationContext) throws Exception { invocationContext.getTarget(), invocationContext.getMethod(), waitingTaskQueue); if (faultToleranceService.areFaultToleranceMetricsEnabled(appName, config)) { - Gauge waitingQueueGauge = metricRegistry.getGauges() + Gauge waitingQueueGauge = metricRegistry.getGauges() .get("ft." + fullMethodSignature + ".bulkhead.waitingQueue.population"); // Register a bulkhead queue metric if there isn't one @@ -416,11 +415,11 @@ private Object bulkhead(InvocationContext invocationContext) throws Exception { return proceededInvocationContext; } - private Long getConcurrentExecutionsCount(int bulkheadValue, Semaphore bulkheadExecutionSemaphore) { + private static Long getConcurrentExecutionsCount(int bulkheadValue, Semaphore bulkheadExecutionSemaphore) { return ((Number) (bulkheadValue - bulkheadExecutionSemaphore.availablePermits())).longValue(); } - private Long getWaitingQueueCount(int waitingTaskQueue, Semaphore bulkheadExecutionQueueSemaphore) { + private static Long getWaitingQueueCount(int waitingTaskQueue, Semaphore bulkheadExecutionQueueSemaphore) { return ((Number) (waitingTaskQueue - bulkheadExecutionQueueSemaphore.availablePermits())).longValue(); } } diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/CircuitBreakerInterceptor.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/CircuitBreakerInterceptor.java index 395aeda9ca9..72750a8032d 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/CircuitBreakerInterceptor.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/CircuitBreakerInterceptor.java @@ -115,7 +115,7 @@ public Object intercept(InvocationContext invocationContext) throws Exception { // Attempt to proceed the InvocationContext with Asynchronous semantics if Fault Tolerance is enabled if (faultToleranceService.isFaultToleranceEnabled(appName, config) - && ((Boolean) FaultToleranceCdiUtils.getEnabledOverrideValue( + && (FaultToleranceCdiUtils.getEnabledOverrideValue( config, CircuitBreaker.class, invocationContext) .orElse(Boolean.TRUE))) { // Only increment the invocations metric if the Retry and Bulkhead annotations aren't present @@ -140,26 +140,25 @@ public Object intercept(InvocationContext invocationContext) throws Exception { if (retry != null) { logger.log(Level.FINE, "Retry annotation found on method, propagating error upwards."); throw ex; + } + Fallback fallback = FaultToleranceCdiUtils.getAnnotation(beanManager, Fallback.class, invocationContext); + + // Only fall back if the annotation hasn't been disabled + if (fallback != null && (FaultToleranceCdiUtils.getEnabledOverrideValue( + config, Fallback.class, invocationContext) + .orElse(Boolean.TRUE))) { + logger.log(Level.FINE, "Fallback annotation found on method, and no Retry annotation - " + + "falling back from CircuitBreaker"); + FallbackPolicy fallbackPolicy = new FallbackPolicy(fallback, config, invocationContext); + proceededInvocationContext = fallbackPolicy.fallback(invocationContext, ex); } else { - Fallback fallback = FaultToleranceCdiUtils.getAnnotation(beanManager, Fallback.class, invocationContext); - - // Only fall back if the annotation hasn't been disabled - if (fallback != null && ((Boolean) FaultToleranceCdiUtils.getEnabledOverrideValue( - config, Fallback.class, invocationContext) - .orElse(Boolean.TRUE))) { - logger.log(Level.FINE, "Fallback annotation found on method, and no Retry annotation - " - + "falling back from CircuitBreaker"); - FallbackPolicy fallbackPolicy = new FallbackPolicy(fallback, config, invocationContext); - proceededInvocationContext = fallbackPolicy.fallback(invocationContext, ex); - } else { - // Increment the failure counter metric - faultToleranceService.incrementCounterMetric(metricRegistry, - "ft." + fullMethodSignature + ".invocations.failed.total", - faultToleranceService.getApplicationName(invocationManager, invocationContext), - config); + // Increment the failure counter metric + faultToleranceService.incrementCounterMetric(metricRegistry, + "ft." + fullMethodSignature + ".invocations.failed.total", + faultToleranceService.getApplicationName(invocationManager, invocationContext), + config); - throw ex; - } + throw ex; } } @@ -191,11 +190,11 @@ private Object circuitBreak(InvocationContext invocationContext) throws Exceptio Class[] failOn = circuitBreaker.failOn(); try { - Optional optionalFailOn = FaultToleranceCdiUtils.getOverrideValue( + Optional optionalFailOn = FaultToleranceCdiUtils.getOverrideValue( config, CircuitBreaker.class, "failOn", invocationContext, String.class); if (optionalFailOn.isPresent()) { - String failOnString = (String) optionalFailOn.get(); - List classList = new ArrayList<>(); + String failOnString = optionalFailOn.get() ; + List> classList = new ArrayList<>(); // Remove any curly or square brackets from the string, as well as any spaces and ".class"es and loop for (String className : failOnString.replaceAll("[\\{\\[ \\]\\}]", "") .replaceAll("\\.class", "").split(",")) { @@ -211,19 +210,19 @@ private Object circuitBreak(InvocationContext invocationContext) throws Exceptio + "Make sure you give the full canonical class name.", cnfe); } - long delay = (Long) FaultToleranceCdiUtils.getOverrideValue( + long delay = FaultToleranceCdiUtils.getOverrideValue( config, CircuitBreaker.class, "delay", invocationContext, Long.class) .orElse(circuitBreaker.delay()); - ChronoUnit delayUnit = (ChronoUnit) FaultToleranceCdiUtils.getOverrideValue( + ChronoUnit delayUnit = FaultToleranceCdiUtils.getOverrideValue( config, CircuitBreaker.class, "delayUnit", invocationContext, ChronoUnit.class) .orElse(circuitBreaker.delayUnit()); - int requestVolumeThreshold = (Integer) FaultToleranceCdiUtils.getOverrideValue( + int requestVolumeThreshold = FaultToleranceCdiUtils.getOverrideValue( config, CircuitBreaker.class, "requestVolumeThreshold", invocationContext, Integer.class) .orElse(circuitBreaker.requestVolumeThreshold()); - double failureRatio = (Double) FaultToleranceCdiUtils.getOverrideValue( + double failureRatio = FaultToleranceCdiUtils.getOverrideValue( config, CircuitBreaker.class, "failureRatio", invocationContext, Double.class) .orElse(circuitBreaker.failureRatio()); - int successThreshold = (Integer) FaultToleranceCdiUtils.getOverrideValue( + int successThreshold = FaultToleranceCdiUtils.getOverrideValue( config, CircuitBreaker.class, "successThreshold", invocationContext, Integer.class) .orElse(circuitBreaker.successThreshold()); @@ -234,13 +233,13 @@ private Object circuitBreak(InvocationContext invocationContext) throws Exceptio invocationContext.getMethod(), circuitBreaker); if (faultToleranceService.areFaultToleranceMetricsEnabled(appName, config)) { - Gauge openTimeGauge = metricRegistry.getGauges() + Gauge openTimeGauge = metricRegistry.getGauges() .get("ft." + fullMethodSignature + ".circuitbreaker.open.total"); - Gauge halfOpenTimeGauge = metricRegistry.getGauges() + Gauge halfOpenTimeGauge = metricRegistry.getGauges() .get("ft." + fullMethodSignature + ".circuitbreaker.halfOpen.total"); - Gauge closedTimeGauge = metricRegistry.getGauges() + Gauge closedTimeGauge = metricRegistry.getGauges() .get("ft." + fullMethodSignature + ".circuitbreaker.closed.total"); registerGaugesIfNecessary(openTimeGauge, halfOpenTimeGauge, closedTimeGauge, metricRegistry, circuitBreakerState, @@ -357,7 +356,7 @@ private Object circuitBreak(InvocationContext invocationContext) throws Exceptio * @param circuitBreakerState The CircuitBreakerState to set the state of * @throws NamingException If the ManagedScheduledExecutor couldn't be found */ - private void scheduleHalfOpen(long delayMillis, CircuitBreakerState circuitBreakerState) throws NamingException { + private static void scheduleHalfOpen(long delayMillis, CircuitBreakerState circuitBreakerState) throws NamingException { Runnable halfOpen = () -> { circuitBreakerState.setCircuitState(CircuitBreakerState.CircuitState.HALF_OPEN); logger.log(Level.FINE, "Setting CircuitBreaker state to half open"); @@ -378,7 +377,7 @@ private void scheduleHalfOpen(long delayMillis, CircuitBreakerState circuitBreak * @param ex The exception to check * @return True if the exception is included in the array */ - private boolean shouldFail(Class[] failOn, Exception ex) { + private static boolean shouldFail(Class[] failOn, Exception ex) { boolean shouldFail = false; if (failOn[0] != Throwable.class) { @@ -388,18 +387,17 @@ private boolean shouldFail(Class[] failOn, Exception ex) { ex.getClass().getSimpleName()); shouldFail = true; break; - } else { - try { - // If we there isn't a direct match, check if the exception is a subclass - ex.getClass().asSubclass(failureClass); - shouldFail = true; - - logger.log(Level.FINER, "Exception {0} is a child of a Throwable in retryOn: {1}", - new String[]{ex.getClass().getSimpleName(), failureClass.getSimpleName()}); - break; - } catch (ClassCastException cce) { - // Om nom nom - } + } + try { + // If we there isn't a direct match, check if the exception is a subclass + ex.getClass().asSubclass(failureClass); + shouldFail = true; + + logger.log(Level.FINER, "Exception {0} is a child of a Throwable in retryOn: {1}", + new String[]{ex.getClass().getSimpleName(), failureClass.getSimpleName()}); + break; + } catch (ClassCastException cce) { + // Om nom nom } } } else { @@ -409,7 +407,7 @@ private boolean shouldFail(Class[] failOn, Exception ex) { return shouldFail; } - private void breakCircuitIfRequired(long failureThreshold, CircuitBreakerState circuitBreakerState, + private static void breakCircuitIfRequired(long failureThreshold, CircuitBreakerState circuitBreakerState, long delayMillis, MetricRegistry metricRegistry, String fullMethodSignature, FaultToleranceService faultToleranceService, String appName, Config config) throws NamingException { // If we're over the failure threshold, open the circuit @@ -429,7 +427,7 @@ private void breakCircuitIfRequired(long failureThreshold, CircuitBreakerState c } } - private void registerGaugesIfNecessary(Gauge openTimeGauge, Gauge halfOpenTimeGauge, Gauge closedTimeGauge, + private static void registerGaugesIfNecessary(Gauge openTimeGauge, Gauge halfOpenTimeGauge, Gauge closedTimeGauge, MetricRegistry metricRegistry, CircuitBreakerState circuitBreakerState, String fullMethodSignature) { // Register a open time gauge if there isn't one diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java index 00e82da1eb3..583abd1c6d5 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java @@ -108,7 +108,7 @@ public Object intercept(InvocationContext invocationContext) throws Exception { // Attempt to proceed the InvocationContext with Asynchronous semantics if Fault Tolerance is enabled for this // method if (faultToleranceService.isFaultToleranceEnabled(appName, config) - && ((Boolean) FaultToleranceCdiUtils.getEnabledOverrideValue( + && (FaultToleranceCdiUtils.getEnabledOverrideValue( config, Retry.class, invocationContext) .orElse(Boolean.TRUE))) { // Increment the invocations metric @@ -127,7 +127,7 @@ public Object intercept(InvocationContext invocationContext) throws Exception { Fallback fallback = FaultToleranceCdiUtils.getAnnotation(beanManager, Fallback.class, invocationContext); // Only fall back if the annotation hasn't been disabled - if (fallback != null && ((Boolean) FaultToleranceCdiUtils.getEnabledOverrideValue( + if (fallback != null && (FaultToleranceCdiUtils.getEnabledOverrideValue( config, Fallback.class, invocationContext) .orElse(Boolean.TRUE))) { logger.log(Level.FINE, "Fallback annotation found on method - falling back from Retry"); @@ -182,12 +182,12 @@ private Object retry(InvocationContext invocationContext) throws Exception { } catch (Exception ex) { Class[] retryOn = retry.retryOn(); try { - Optional optionalRetryOn = FaultToleranceCdiUtils.getOverrideValue( + Optional optionalRetryOn = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "retryOn", invocationContext, String.class); if (optionalRetryOn.isPresent()) { - String retryOnString = ((String) optionalRetryOn.get()); + String retryOnString = optionalRetryOn.get(); - List classList = new ArrayList<>(); + List> classList = new ArrayList<>(); // Remove any curly or square brackets from the string, as well as any spaces and ".class"es for (String className : retryOnString.replaceAll("[\\{\\[ \\]\\}]", "") @@ -206,12 +206,12 @@ private Object retry(InvocationContext invocationContext) throws Exception { Class[] abortOn = retry.abortOn(); try { - Optional optionalAbortOn = FaultToleranceCdiUtils.getOverrideValue( + Optional optionalAbortOn = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "abortOn", invocationContext, String.class); if (optionalAbortOn.isPresent()) { - String abortOnString = (String) optionalAbortOn.get(); + String abortOnString = optionalAbortOn.get(); - List classList = new ArrayList<>(); + List> classList = new ArrayList<>(); // Remove any curly or square brackets from the string, as well as any spaces and ".class"es for (String className : abortOnString.replaceAll("[\\{\\[ \\]\\}]", "") @@ -233,29 +233,29 @@ private Object retry(InvocationContext invocationContext) throws Exception { throw ex; } - int maxRetries = (Integer) FaultToleranceCdiUtils.getOverrideValue( + int maxRetries = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "maxRetries", invocationContext, Integer.class) .orElse(retry.maxRetries()); - long delay = (Long) FaultToleranceCdiUtils.getOverrideValue( + long delay = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "delay", invocationContext, Long.class) .orElse(retry.delay()); // Look for a String and cast to ChronoUnit - Use the Common Sense Convertor - ChronoUnit delayUnit = (ChronoUnit) FaultToleranceCdiUtils.getOverrideValue( - config, Retry.class, "delayUnit", invocationContext, String.class) + ChronoUnit delayUnit = FaultToleranceCdiUtils.getOverrideValue( + config, Retry.class, "delayUnit", invocationContext, ChronoUnit.class) .orElse(retry.delayUnit()); - long maxDuration = (Long) FaultToleranceCdiUtils.getOverrideValue( + long maxDuration = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "maxDuration", invocationContext, Long.class) .orElse(retry.maxDuration()); // Look for a String and cast to ChronoUnit - Use the Common Sense Convertor - ChronoUnit durationUnit = (ChronoUnit) FaultToleranceCdiUtils.getOverrideValue( - config, Retry.class, "durationUnit", invocationContext, String.class) + ChronoUnit durationUnit = FaultToleranceCdiUtils.getOverrideValue( + config, Retry.class, "durationUnit", invocationContext, ChronoUnit.class) .orElse(retry.durationUnit()); - long jitter = (Long) FaultToleranceCdiUtils.getOverrideValue( + long jitter = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "jitter", invocationContext, Long.class) .orElse(retry.jitter()); // Look for a String and cast to ChronoUnit - Use the Common Sense Convertor - ChronoUnit jitterDelayUnit = (ChronoUnit) FaultToleranceCdiUtils.getOverrideValue( - config, Retry.class, "jitterDelayUnit", invocationContext, String.class) + ChronoUnit jitterDelayUnit = FaultToleranceCdiUtils.getOverrideValue( + config, Retry.class, "jitterDelayUnit", invocationContext, ChronoUnit.class) .orElse(retry.jitterDelayUnit()); long delayMillis = Duration.of(delay, delayUnit).toMillis(); @@ -411,7 +411,7 @@ private Object retry(InvocationContext invocationContext) throws Exception { * @param ex The caught exception * @return True if retry should be attempted. */ - private boolean shouldRetry(Class[] retryOn, Class[] abortOn, + private static boolean shouldRetry(Class[] retryOn, Class[] abortOn, Exception ex) { boolean shouldRetry = false; @@ -423,18 +423,17 @@ private boolean shouldRetry(Class[] retryOn, Class[] retryOn, Class timeoutFuture = null; long timeoutMillis = Duration.of(value, unit).toMillis(); long timeoutTime = System.currentTimeMillis() + timeoutMillis; long executionStartTime = System.nanoTime(); @@ -271,7 +270,7 @@ private Object timeout(InvocationContext invocationContext) throws Exception { * @return A future that can be cancelled if the method execution completes before the interrupt happens * @throws NamingException If the configured ManagedScheduledExecutorService could not be found */ - private Future startTimeout(long timeoutMillis) throws NamingException { + private static Future startTimeout(long timeoutMillis) throws NamingException { final Thread thread = Thread.currentThread(); Runnable timeoutTask = () -> { @@ -290,7 +289,7 @@ private Future startTimeout(long timeoutMillis) throws NamingException { * Helper method that stops the scheduled interrupt. * @param timeoutFuture The scheduled interrupt to cancel. */ - private void stopTimeout(Future timeoutFuture) { + private static void stopTimeout(Future timeoutFuture) { if (timeoutFuture != null) { timeoutFuture.cancel(true); } diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/fallback/FallbackPolicy.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/fallback/FallbackPolicy.java index 94b1424d8e1..b3669a0d732 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/fallback/FallbackPolicy.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/fallback/FallbackPolicy.java @@ -66,18 +66,19 @@ public class FallbackPolicy { private static final Logger logger = Logger.getLogger(FallbackPolicy.class.getName()); - private final Class fallbackClass; + private final Class> fallbackClass; private final String fallbackMethod; + @SuppressWarnings("unchecked") public FallbackPolicy(Fallback fallback, Config config, InvocationContext invocationContext) throws ClassNotFoundException { - fallbackClass = (Class) Thread.currentThread().getContextClassLoader().loadClass( - (String) FaultToleranceCdiUtils.getOverrideValue(config, Fallback.class, "value", - invocationContext, String.class) - .orElse(fallback.value().getName())); + fallbackClass = (Class>) Thread.currentThread().getContextClassLoader().loadClass( + FaultToleranceCdiUtils.getOverrideValue(config, Fallback.class, "value", + invocationContext, Class.class) + .orElse(fallback.value()).getName()); - fallbackMethod = (String) FaultToleranceCdiUtils.getOverrideValue(config, Fallback.class, - "fallbackMethod", invocationContext, String.class) + fallbackMethod = FaultToleranceCdiUtils.getOverrideValue(config, Fallback.class, + "fallbackMethod", invocationContext, String.class) .orElse(fallback.fallbackMethod()); } diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/BulkheadValidator.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/BulkheadValidator.java index 255312dc913..14f52c30fe2 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/BulkheadValidator.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/BulkheadValidator.java @@ -58,11 +58,11 @@ public class BulkheadValidator { * @param config The config to get any override values from */ public static void validateAnnotation(Bulkhead bulkhead, AnnotatedMethod annotatedMethod, Config config) { - int value = (Integer) FaultToleranceCdiUtils.getOverrideValue( + int value = FaultToleranceCdiUtils.getOverrideValue( config, Bulkhead.class, "value", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Integer.class) .orElse(bulkhead.value()); - int waitingTaskQueue = (Integer) FaultToleranceCdiUtils.getOverrideValue( + int waitingTaskQueue = FaultToleranceCdiUtils.getOverrideValue( config, Bulkhead.class, "waitingTaskQueue", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Integer.class) .orElse(bulkhead.waitingTaskQueue()); diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/CircuitBreakerValidator.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/CircuitBreakerValidator.java index 73713c05756..9cf40b23215 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/CircuitBreakerValidator.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/CircuitBreakerValidator.java @@ -59,22 +59,22 @@ public class CircuitBreakerValidator { */ public static void validateAnnotation(CircuitBreaker circuitBreaker, AnnotatedMethod annotatedMethod, Config config) { - long delay = (Long) FaultToleranceCdiUtils.getOverrideValue( + long delay = FaultToleranceCdiUtils.getOverrideValue( config, CircuitBreaker.class, "delay", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Long.class) .orElse(circuitBreaker.delay()); - int requestVolumeThreshold = (Integer) FaultToleranceCdiUtils.getOverrideValue( + int requestVolumeThreshold = FaultToleranceCdiUtils.getOverrideValue( config, CircuitBreaker.class, "requestVolumeThreshold", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Integer.class) .orElse(circuitBreaker.requestVolumeThreshold()); - double failureRatio = (Double) FaultToleranceCdiUtils.getOverrideValue( + double failureRatio = FaultToleranceCdiUtils.getOverrideValue( config, CircuitBreaker.class, "failureRatio", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Double.class) .orElse(circuitBreaker.failureRatio()); - int successThreshold = (Integer) FaultToleranceCdiUtils.getOverrideValue( + int successThreshold = FaultToleranceCdiUtils.getOverrideValue( config, CircuitBreaker.class, "successThreshold", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Integer.class) .orElse(circuitBreaker.successThreshold()); diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/FallbackValidator.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/FallbackValidator.java index f798920ce4e..1859f71b15a 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/FallbackValidator.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/FallbackValidator.java @@ -65,32 +65,32 @@ public class FallbackValidator { public static void validateAnnotation(Fallback fallback, AnnotatedMethod annotatedMethod, Config config) throws ClassNotFoundException, NoSuchMethodException { // Get the fallbackMethod - String fallbackMethod = (String) FaultToleranceCdiUtils.getOverrideValue( + String fallbackMethod = FaultToleranceCdiUtils.getOverrideValue( config, Fallback.class, "fallbackMethod", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), String.class) .orElse(fallback.fallbackMethod()); // Get the fallbackClass, and check that it can be found - Class fallbackClass = (Class) Thread.currentThread() - .getContextClassLoader().loadClass((String) FaultToleranceCdiUtils + @SuppressWarnings("unchecked") + Class> fallbackClass = (Class>) Thread.currentThread() + .getContextClassLoader().loadClass(FaultToleranceCdiUtils .getOverrideValue(config, Fallback.class, "value", annotatedMethod.getJavaMember().getName(), - annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), String.class) - .orElse(fallback.value().getName())); + annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Class.class) + .orElse(fallback.value()).getName()); // Validate the annotated method if (fallbackMethod != null && !fallbackMethod.isEmpty()) { if (fallbackClass != null && fallbackClass != Fallback.DEFAULT.class) { throw new FaultToleranceDefinitionException("Both a fallback class and method have been set."); - } else { - try { - if (annotatedMethod.getJavaMember().getDeclaringClass().getDeclaredMethod(fallbackMethod, - annotatedMethod.getJavaMember().getParameterTypes()).getReturnType() - != annotatedMethod.getJavaMember().getReturnType()) { - throw new FaultToleranceDefinitionException("Return type of fallback method does not match."); - } - } catch (NoSuchMethodException ex) { - throw new FaultToleranceDefinitionException("Could not find fallback method: " + fallbackMethod, ex); + } + try { + if (annotatedMethod.getJavaMember().getDeclaringClass().getDeclaredMethod(fallbackMethod, + annotatedMethod.getJavaMember().getParameterTypes()).getReturnType() + != annotatedMethod.getJavaMember().getReturnType()) { + throw new FaultToleranceDefinitionException("Return type of fallback method does not match."); } + } catch (NoSuchMethodException ex) { + throw new FaultToleranceDefinitionException("Could not find fallback method: " + fallbackMethod, ex); } } else if (fallbackClass != null && fallbackClass != Fallback.DEFAULT.class) { if (fallbackClass.getDeclaredMethod(FALLBACK_HANDLER_METHOD_NAME, ExecutionContext.class).getReturnType() diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/RetryValidator.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/RetryValidator.java index 77c4f4d5666..bda65c74105 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/RetryValidator.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/RetryValidator.java @@ -58,22 +58,22 @@ public class RetryValidator { * @param config The config to get any override values from */ public static void validateAnnotation(Retry retry, AnnotatedMethod annotatedMethod, Config config) { - int maxRetries = (Integer) FaultToleranceCdiUtils.getOverrideValue( + int maxRetries = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "maxRetries", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Integer.class) .orElse(retry.maxRetries()); - long delay = (Long) FaultToleranceCdiUtils.getOverrideValue( + long delay = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "delay", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Long.class) .orElse(retry.delay()); - long maxDuration = (Long) FaultToleranceCdiUtils.getOverrideValue( + long maxDuration = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "maxDuration", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Long.class) .orElse(retry.maxDuration()); - long jitter = (Long) FaultToleranceCdiUtils.getOverrideValue( + long jitter = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "jitter", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Long.class) .orElse(retry.jitter()); diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/TimeoutValidator.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/TimeoutValidator.java index 0a1fc0a3786..be554f1265c 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/TimeoutValidator.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/TimeoutValidator.java @@ -51,7 +51,7 @@ */ public class TimeoutValidator { public static void validateAnnotation(Timeout timeout, AnnotatedMethod annotatedMethod, Config config) { - long value = (Long) FaultToleranceCdiUtils.getOverrideValue( + long value = FaultToleranceCdiUtils.getOverrideValue( config, Timeout.class, "value", annotatedMethod.getJavaMember().getName(), annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Long.class) .orElse(timeout.value()); From 143e9f673817b1cc0cc027ecff89a21ba6fe3c76 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Thu, 28 Mar 2019 14:16:25 +0100 Subject: [PATCH 087/108] PAYARA-3468 fixed conversion of config overrides from String --- .../interceptors/RetryInterceptor.java | 6 +++--- .../interceptors/TimeoutInterceptor.java | 2 +- .../interceptors/fallback/FallbackPolicy.java | 12 +++++++----- .../validators/FallbackValidator.java | 17 +++++++++++------ 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java index 583abd1c6d5..3175285badc 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java @@ -241,21 +241,21 @@ private Object retry(InvocationContext invocationContext) throws Exception { .orElse(retry.delay()); // Look for a String and cast to ChronoUnit - Use the Common Sense Convertor ChronoUnit delayUnit = FaultToleranceCdiUtils.getOverrideValue( - config, Retry.class, "delayUnit", invocationContext, ChronoUnit.class) + config, Retry.class, "delayUnit", invocationContext, String.class).map(ChronoUnit::valueOf) .orElse(retry.delayUnit()); long maxDuration = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "maxDuration", invocationContext, Long.class) .orElse(retry.maxDuration()); // Look for a String and cast to ChronoUnit - Use the Common Sense Convertor ChronoUnit durationUnit = FaultToleranceCdiUtils.getOverrideValue( - config, Retry.class, "durationUnit", invocationContext, ChronoUnit.class) + config, Retry.class, "durationUnit", invocationContext, String.class).map(ChronoUnit::valueOf) .orElse(retry.durationUnit()); long jitter = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "jitter", invocationContext, Long.class) .orElse(retry.jitter()); // Look for a String and cast to ChronoUnit - Use the Common Sense Convertor ChronoUnit jitterDelayUnit = FaultToleranceCdiUtils.getOverrideValue( - config, Retry.class, "jitterDelayUnit", invocationContext, ChronoUnit.class) + config, Retry.class, "jitterDelayUnit", invocationContext, String.class).map(ChronoUnit::valueOf) .orElse(retry.jitterDelayUnit()); long delayMillis = Duration.of(delay, delayUnit).toMillis(); diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/TimeoutInterceptor.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/TimeoutInterceptor.java index 6541f27cb7c..315c8e4da13 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/TimeoutInterceptor.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/TimeoutInterceptor.java @@ -194,7 +194,7 @@ private Object timeout(InvocationContext invocationContext) throws Exception { .orElse(timeout.value()); // Look for a String and cast to ChronoUnit - Use the Common Sense Convertor ChronoUnit unit = FaultToleranceCdiUtils.getOverrideValue( - config, Timeout.class, "unit", invocationContext, ChronoUnit.class) + config, Timeout.class, "unit", invocationContext, String.class).map(ChronoUnit::valueOf) .orElse(timeout.unit()); Future timeoutFuture = null; diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/fallback/FallbackPolicy.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/fallback/FallbackPolicy.java index b3669a0d732..6d68bfddbca 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/fallback/FallbackPolicy.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/fallback/FallbackPolicy.java @@ -43,6 +43,7 @@ import static fish.payara.microprofile.faulttolerance.FaultToleranceService.FALLBACK_HANDLER_METHOD_NAME; import fish.payara.microprofile.faulttolerance.cdi.FaultToleranceCdiUtils; import java.lang.reflect.Method; +import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; import javax.interceptor.InvocationContext; @@ -72,11 +73,12 @@ public class FallbackPolicy { @SuppressWarnings("unchecked") public FallbackPolicy(Fallback fallback, Config config, InvocationContext invocationContext) throws ClassNotFoundException { - fallbackClass = (Class>) Thread.currentThread().getContextClassLoader().loadClass( - FaultToleranceCdiUtils.getOverrideValue(config, Fallback.class, "value", - invocationContext, Class.class) - .orElse(fallback.value()).getName()); - + Optional className = FaultToleranceCdiUtils.getOverrideValue(config, Fallback.class, "value", + invocationContext, String.class); + fallbackClass = className.isPresent() + ? (Class>) Thread.currentThread().getContextClassLoader() + .loadClass(className.get()) + : fallback.value(); fallbackMethod = FaultToleranceCdiUtils.getOverrideValue(config, Fallback.class, "fallbackMethod", invocationContext, String.class) .orElse(fallback.fallbackMethod()); diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/FallbackValidator.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/FallbackValidator.java index 1859f71b15a..e50acdc68c1 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/FallbackValidator.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/validators/FallbackValidator.java @@ -40,6 +40,9 @@ package fish.payara.microprofile.faulttolerance.validators; import static fish.payara.microprofile.faulttolerance.FaultToleranceService.FALLBACK_HANDLER_METHOD_NAME; + +import java.util.Optional; + import fish.payara.microprofile.faulttolerance.cdi.FaultToleranceCdiUtils; import javax.enterprise.inject.spi.AnnotatedMethod; import org.eclipse.microprofile.config.Config; @@ -71,13 +74,15 @@ public static void validateAnnotation(Fallback fallback, AnnotatedMethod anno .orElse(fallback.fallbackMethod()); // Get the fallbackClass, and check that it can be found - @SuppressWarnings("unchecked") - Class> fallbackClass = (Class>) Thread.currentThread() - .getContextClassLoader().loadClass(FaultToleranceCdiUtils + Optional fallbackClassName = FaultToleranceCdiUtils .getOverrideValue(config, Fallback.class, "value", annotatedMethod.getJavaMember().getName(), - annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), Class.class) - .orElse(fallback.value()).getName()); - + annotatedMethod.getJavaMember().getDeclaringClass().getCanonicalName(), String.class); + @SuppressWarnings("unchecked") + Class> fallbackClass = fallbackClassName.isPresent() + ? (Class>) Thread.currentThread().getContextClassLoader() + .loadClass(fallbackClassName.get()) + : fallback.value(); + // Validate the annotated method if (fallbackMethod != null && !fallbackMethod.isEmpty()) { if (fallbackClass != null && fallbackClass != Fallback.DEFAULT.class) { From 40cbc2ea7739b83dfe2e1e39c0ecc58a0eb269dd Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Thu, 28 Mar 2019 16:13:05 +0100 Subject: [PATCH 088/108] PAYARA-3468 extract ChronoUnit from Config as ChronoUnit.class --- .../faulttolerance/interceptors/RetryInterceptor.java | 6 +++--- .../faulttolerance/interceptors/TimeoutInterceptor.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java index 3175285badc..583abd1c6d5 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/RetryInterceptor.java @@ -241,21 +241,21 @@ private Object retry(InvocationContext invocationContext) throws Exception { .orElse(retry.delay()); // Look for a String and cast to ChronoUnit - Use the Common Sense Convertor ChronoUnit delayUnit = FaultToleranceCdiUtils.getOverrideValue( - config, Retry.class, "delayUnit", invocationContext, String.class).map(ChronoUnit::valueOf) + config, Retry.class, "delayUnit", invocationContext, ChronoUnit.class) .orElse(retry.delayUnit()); long maxDuration = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "maxDuration", invocationContext, Long.class) .orElse(retry.maxDuration()); // Look for a String and cast to ChronoUnit - Use the Common Sense Convertor ChronoUnit durationUnit = FaultToleranceCdiUtils.getOverrideValue( - config, Retry.class, "durationUnit", invocationContext, String.class).map(ChronoUnit::valueOf) + config, Retry.class, "durationUnit", invocationContext, ChronoUnit.class) .orElse(retry.durationUnit()); long jitter = FaultToleranceCdiUtils.getOverrideValue( config, Retry.class, "jitter", invocationContext, Long.class) .orElse(retry.jitter()); // Look for a String and cast to ChronoUnit - Use the Common Sense Convertor ChronoUnit jitterDelayUnit = FaultToleranceCdiUtils.getOverrideValue( - config, Retry.class, "jitterDelayUnit", invocationContext, String.class).map(ChronoUnit::valueOf) + config, Retry.class, "jitterDelayUnit", invocationContext, ChronoUnit.class) .orElse(retry.jitterDelayUnit()); long delayMillis = Duration.of(delay, delayUnit).toMillis(); diff --git a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/TimeoutInterceptor.java b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/TimeoutInterceptor.java index 315c8e4da13..6541f27cb7c 100644 --- a/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/TimeoutInterceptor.java +++ b/appserver/payara-appserver-modules/microprofile/fault-tolerance/src/main/java/fish/payara/microprofile/faulttolerance/interceptors/TimeoutInterceptor.java @@ -194,7 +194,7 @@ private Object timeout(InvocationContext invocationContext) throws Exception { .orElse(timeout.value()); // Look for a String and cast to ChronoUnit - Use the Common Sense Convertor ChronoUnit unit = FaultToleranceCdiUtils.getOverrideValue( - config, Timeout.class, "unit", invocationContext, String.class).map(ChronoUnit::valueOf) + config, Timeout.class, "unit", invocationContext, ChronoUnit.class) .orElse(timeout.unit()); Future timeoutFuture = null; From fd0fa36e8a228a3d4a576bd98a1bda4c8151db4a Mon Sep 17 00:00:00 2001 From: Andrew Pielage Date: Thu, 28 Mar 2019 17:28:49 +0000 Subject: [PATCH 089/108] PAYARA-3676 variable naming and get rid of redundant try-catches --- .../enterprise/admin/cli/LoginCommand.java | 12 ++++------- .../admin/cli/remote/RemoteCLICommand.java | 8 ++++---- .../admin/cli/remote/RemoteCommand.java | 8 ++++---- .../servermgmt/cli/CreateDomainCommand.java | 20 ++++++++----------- .../admin/util/AsadminTrustManager.java | 13 ++++-------- .../cli/cluster/LocalInstanceCommand.java | 8 ++++---- .../admin/cli/cluster/SetupSshKey.java | 8 ++++---- .../security/store/AsadminSecurityUtil.java | 8 ++++---- 8 files changed, 36 insertions(+), 49 deletions(-) diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java index 21249494fe2..a0b16489afb 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java @@ -123,20 +123,16 @@ protected int executeCommand() throws CommandException, CommandValidationExcepti private String getAdminUser() { String user = null; - try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { + try (ConsoleReader console = new ConsoleReader(System.in, System.out, null)) { String defuser = programOpts.getUser(); if (defuser == null) { defuser = SystemPropertyConstants.DEFAULT_ADMIN_USER; } - if (cons != null) { - cons.setPrompt(strings.get("AdminUserPrompt", defuser)); + if (console != null) { + console.setPrompt(strings.get("AdminUserPrompt", defuser)); String val = null; - try { - val = cons.readLine(); - } catch (IOException ioe) { - logger.log(Level.WARNING, "Error reading input", ioe); - } + val = console.readLine(); if (val != null && val.length() > 0){ user = val; } else { diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java index 5139c8e3054..06483037cdf 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java @@ -173,8 +173,8 @@ public void fetchCommandModel() throws CommandException { */ @Override protected boolean updateAuthentication() { - try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { - if (programOpts.isInteractive() && cons != null) { + try (ConsoleReader console = new ConsoleReader(System.in, System.out, null)) { + if (programOpts.isInteractive() && console != null) { // if appropriate, tell the user why authentication failed PasswordLocation pwloc = programOpts.getPasswordLocation(); if (pwloc == PasswordLocation.PASSWORD_FILE) { @@ -195,10 +195,10 @@ protected boolean updateAuthentication() { // correct username to begin with and all we need is the // password. if (programOpts.getUser() == null) { - cons.setPrompt(strings.get("AdminUserPrompt")); + console.setPrompt(strings.get("AdminUserPrompt")); try { - user = cons.readLine(); + user = console.readLine(); } catch (IOException ioe) { logger.log(Level.WARNING, "Error reading input", ioe); } diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java index 3f4f8a81e8c..b337cf07405 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java @@ -135,8 +135,8 @@ public void fetchCommandModel() throws CommandException { */ @Override protected boolean updateAuthentication() { - try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { - if (programOpts.isInteractive() && cons != null) { + try (ConsoleReader console = new ConsoleReader(System.in, System.out, null)) { + if (programOpts.isInteractive() && console != null) { // if appropriate, tell the user why authentication failed PasswordLocation pwloc = programOpts.getPasswordLocation(); if (pwloc == PasswordLocation.PASSWORD_FILE) { @@ -156,10 +156,10 @@ protected boolean updateAuthentication() { // correct username to begin with and all we need is the // password. if (programOpts.getUser() == null) { - cons.setPrompt(strings.get("AdminUserPrompt")); + console.setPrompt(strings.get("AdminUserPrompt")); try { - user = cons.readLine(); + user = console.readLine(); } catch (IOException ioe) { logger.log(Level.WARNING, "Error reading input", ioe); } diff --git a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java index a3d7564aeb3..3622d156544 100644 --- a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java +++ b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java @@ -228,24 +228,20 @@ protected void validate() throws CommandException, CommandValidationException { if (console != null && programOpts.isInteractive()) { console.setPrompt(STRINGS.get("AdminUserRequiredPrompt", SystemPropertyConstants.DEFAULT_ADMIN_USER)); - try { - String val = console.readLine(); - - if (ok(val)) { - programOpts.setUser(val); - if (adminPassword == null) { - char[] pwdArr = getAdminPassword(); - adminPassword = pwdArr != null ? new String(pwdArr) : null; - } + String val = console.readLine(); + + if (ok(val)) { + programOpts.setUser(val); + if (adminPassword == null) { + char[] pwdArr = getAdminPassword(); + adminPassword = pwdArr != null ? new String(pwdArr) : null; } - } catch (IOException ioe) { - logger.log(Level.WARNING, "Error reading input", ioe); } } else { throw new CommandValidationException(STRINGS.get("AdminUserRequired")); } } catch (IOException ioe) { - logger.log(Level.WARNING, "Error instantiating console", ioe); + logger.log(Level.WARNING, "Error reading input", ioe); } } diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java index 89fa3079e2e..bf50c190b4c 100644 --- a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java @@ -168,18 +168,13 @@ public X509Certificate[] getAcceptedIssuers() { private boolean isItOKToAddCertToTrustStore(X509Certificate c) { String result = null; - try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { - if (!interactive || cons == null) { + try (ConsoleReader console = new ConsoleReader(System.in, System.out, null)) { + if (!interactive || console == null) { return true; } - cons.setPrompt(c.toString()); - - try { - result = cons.readLine(STRING_MANAGER.get("certificateTrustPrompt")); - } catch (IOException ioe) { - logger.log(Level.WARNING, "Error reading input", ioe); - } + console.setPrompt(c.toString()); + result = console.readLine(STRING_MANAGER.get("certificateTrustPrompt")); } catch (IOException ioe) { logger.log(Level.WARNING, "Error instantiating console", ioe); } diff --git a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java index 5a47d8a0230..e13c0110d77 100644 --- a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java +++ b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java @@ -500,9 +500,9 @@ private int updateDasPort(Properties dasprops, int port, File propfile) { Integer.toString(programOpts.getPort()))); port = programOpts.getPort(); } else { - try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { - if (cons != null) { - String line = cons.readLine(Strings.get("Instance.oldDasPropertiesPrompt", + try (ConsoleReader console = new ConsoleReader(System.in, System.out, null)) { + if (console != null) { + String line = console.readLine(Strings.get("Instance.oldDasPropertiesPrompt", propfile.toString(), Integer.toString(port), Integer.toString(programOpts.getPort()))); while (line != null && line.length() > 0) { @@ -513,7 +513,7 @@ private int updateDasPort(Properties dasprops, int port, File propfile) { } catch (NumberFormatException nfex) { //try again } - line = cons.readLine(Strings.get("Instance.reenterPort", Integer.toString(programOpts.getPort()))); + line = console.readLine(Strings.get("Instance.reenterPort", Integer.toString(programOpts.getPort()))); } } else { logger.info(Strings.get("Instance.oldDasPropertiesWrong", diff --git a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java index d55e0ecc527..0c2734c5f2a 100644 --- a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java +++ b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java @@ -172,12 +172,12 @@ private boolean promptForKeyGeneration() { if (!programOpts.isInteractive()) return false; - try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { - if (cons != null) { + try (ConsoleReader console = new ConsoleReader(System.in, System.out, null)) { + if (console != null) { String val = null; do { - cons.setPrompt(Strings.get("GenerateKeyPairPrompt", getRemoteUser(), Arrays.toString(hosts))); - val = cons.readLine(); + console.setPrompt(Strings.get("GenerateKeyPairPrompt", getRemoteUser(), Arrays.toString(hosts))); + val = console.readLine(); if (val != null && (val.equalsIgnoreCase("yes") || val.equalsIgnoreCase("y"))) { if (logger.isLoggable(Level.FINER)) { logger.finer("Generate key!"); diff --git a/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java b/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java index 48e91fb6341..951b44855b1 100644 --- a/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java +++ b/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java @@ -174,13 +174,13 @@ private AsadminSecurityUtil(final char[] commandLineMasterPassword, final boolea * @return the password to the client side truststore */ private char[] promptForPassword() throws IOException { - try (ConsoleReader cons = new ConsoleReader(System.in, System.out, null)) { - if (cons != null) { + try (ConsoleReader console = new ConsoleReader(System.in, System.out, null)) { + if (console != null) { // Don't echo anything when reading char echoCharacter = 0; - cons.setEchoCharacter(echoCharacter); + console.setEchoCharacter(echoCharacter); - String line = cons.readLine(strmgr.get("certificateDbPrompt")); + String line = console.readLine(strmgr.get("certificateDbPrompt")); return line.toCharArray(); } } catch (IOException ioe) { From 4c9f6bba34b11f1f820f7fa4fe98f141464d99e0 Mon Sep 17 00:00:00 2001 From: Andrew Pielage Date: Fri, 29 Mar 2019 12:37:28 +0000 Subject: [PATCH 090/108] PAYARA-3676 Copyright --- .../main/java/com/sun/enterprise/admin/cli/LoginCommand.java | 2 +- .../com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java | 2 +- .../java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java | 2 +- .../enterprise/admin/servermgmt/cli/CreateDomainCommand.java | 2 +- .../java/com/sun/enterprise/admin/util/AsadminTrustManager.java | 2 +- .../sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java | 2 +- .../com/sun/enterprise/admin/cli/cluster/SetupLocalDcom.java | 2 +- .../java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java | 2 +- .../com/sun/enterprise/security/store/AsadminSecurityUtil.java | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java index a0b16489afb..275b906d1b3 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/LoginCommand.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.admin.cli; diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java index 06483037cdf..8baef9e6136 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.admin.cli.remote; diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java index b337cf07405..65891816811 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.admin.cli.remote; diff --git a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java index 3622d156544..db4754da289 100644 --- a/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java +++ b/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/cli/CreateDomainCommand.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.admin.servermgmt.cli; diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java index bf50c190b4c..7e1c13e1ee2 100644 --- a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/AsadminTrustManager.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] Payara Foundation and/or affiliates +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.admin.util; diff --git a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java index e13c0110d77..5c8c95a90b1 100644 --- a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java +++ b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/LocalInstanceCommand.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portios Copyright [2019] Payara Foundation and/or affiliates +// Portios Copyright [2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.admin.cli.cluster; diff --git a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupLocalDcom.java b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupLocalDcom.java index 678a6dbf2b5..c4ae2161074 100644 --- a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupLocalDcom.java +++ b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupLocalDcom.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2019] Payara Foundation and/or affiliates +// Portions Copyright [2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.admin.cli.cluster; diff --git a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java index 0c2734c5f2a..25e1c4a27e4 100644 --- a/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java +++ b/nucleus/cluster/cli/src/main/java/com/sun/enterprise/admin/cli/cluster/SetupSshKey.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2019[ Payara Foundation and/or affiliates +// Portions Copyright [2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.admin.cli.cluster; diff --git a/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java b/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java index 951b44855b1..16a1539d372 100644 --- a/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java +++ b/nucleus/common/common-util/src/main/java/com/sun/enterprise/security/store/AsadminSecurityUtil.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.security.store; import java.io.BufferedInputStream; From aa85a285c9a5c4e13b9983e3756ccc15a751b565 Mon Sep 17 00:00:00 2001 From: Cousjava Date: Fri, 29 Mar 2019 14:28:18 +0000 Subject: [PATCH 091/108] PAYARA-3692 Space at the end of MysqlDataSource --- .../lib/install/databases/dbvendormapping/ds.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appserver/jdbc/templates/src/main/resources/glassfish/lib/install/databases/dbvendormapping/ds.properties b/appserver/jdbc/templates/src/main/resources/glassfish/lib/install/databases/dbvendormapping/ds.properties index 0e87e794683..3674d307154 100644 --- a/appserver/jdbc/templates/src/main/resources/glassfish/lib/install/databases/dbvendormapping/ds.properties +++ b/appserver/jdbc/templates/src/main/resources/glassfish/lib/install/databases/dbvendormapping/ds.properties @@ -37,7 +37,7 @@ # only if the new code is made subject to such option by the copyright # holder. # -# Portions Copyright [2017-2018] [Payara Foundation and/or its affiliates] +# Portions Copyright [2017-2019] [Payara Foundation and/or its affiliates] ORACLE=oracle.jdbc.pool.OracleDataSource DERBY=org.apache.derby.jdbc.ClientDataSource40 @@ -53,7 +53,7 @@ SYBASE=com.sybase.jdbc2.jdbc.SybDataSource POINTBASE=com.pointbase.jdbc.jdbcDataSource CLOUDSCAPE=com.cloudscape.core.BasicDataSource INFORMIX=com.informix.jdbcx.IfxDataSource - MYSQL=com.mysql.jdbc.jdbc2.optional.MysqlDataSource +MYSQL=com.mysql.jdbc.jdbc2.optional.MysqlDataSource MYSQL8=com.mysql.cj.jdbc.MysqlDataSource POSTGRESQL=org.postgresql.ds.PGSimpleDataSource DATADIRECT-DB2=com.ddtek.jdbcx.db2.DB2DataSource From e99a036033797f6cdc8b1745bbc641f717fa7bb1 Mon Sep 17 00:00:00 2001 From: Gaurav Gupta Date: Sat, 30 Mar 2019 17:43:38 +0530 Subject: [PATCH 092/108] PAYARA-3515 Fix setting authentication realm on Virtual Server with a property --- .../security/ee/SecurityDeployer.java | 2 +- .../com/sun/enterprise/web/WebContainer.java | 41 +++++++++++-------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/ee/SecurityDeployer.java b/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/ee/SecurityDeployer.java index 589372e938c..645d5e64aaa 100644 --- a/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/ee/SecurityDeployer.java +++ b/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/ee/SecurityDeployer.java @@ -246,7 +246,7 @@ public MetaData getMetaData() { * @param remove boolean indicated whether any existing policy statements are removed form context before translation * @throws DeploymentException */ - private void loadPolicy(WebBundleDescriptor webDescriptor, boolean remove) throws DeploymentException { + public void loadPolicy(WebBundleDescriptor webDescriptor, boolean remove) throws DeploymentException { try { if (webDescriptor != null) { if (remove) { diff --git a/appserver/web/web-glue/src/main/java/com/sun/enterprise/web/WebContainer.java b/appserver/web/web-glue/src/main/java/com/sun/enterprise/web/WebContainer.java index 3d0d7da7071..5911cbb8166 100644 --- a/appserver/web/web-glue/src/main/java/com/sun/enterprise/web/WebContainer.java +++ b/appserver/web/web-glue/src/main/java/com/sun/enterprise/web/WebContainer.java @@ -114,7 +114,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.stream.Collectors; import javax.imageio.ImageIO; import javax.inject.Inject; @@ -204,6 +203,8 @@ import com.sun.enterprise.deployment.Application; import com.sun.enterprise.deployment.WebBundleDescriptor; import com.sun.enterprise.deployment.WebComponentDescriptor; +import com.sun.enterprise.security.PolicyLoader; +import com.sun.enterprise.security.ee.SecurityDeployer; import com.sun.enterprise.security.integration.RealmInitializer; import com.sun.enterprise.server.logging.LoggingRuntime; import com.sun.enterprise.util.Result; @@ -382,6 +383,12 @@ public class WebContainer implements org.glassfish.api.container.Container, Post @Inject ServerConfigLookup serverConfigLookup; + @Inject + private PolicyLoader policyLoader; + + @Inject + private SecurityDeployer securityDeployer; + protected JspProbeProvider jspProbeProvider; protected RequestProbeProvider requestProbeProvider; protected ServletProbeProvider servletProbeProvider; @@ -595,6 +602,7 @@ public void postConstruct() { createHosts(httpService, securityService); } + policyLoader.loadPolicy(); loadSystemDefaultWebModules(); // _lifecycle.fireLifecycleEvent(START_EVENT, null); @@ -1503,6 +1511,7 @@ public void loadDefaultWebModule(VirtualServer virtualServer) { protected void loadStandaloneWebModule(VirtualServer virtualServer, WebModuleConfig webModuleConfig) { try { loadWebModule(virtualServer, webModuleConfig, "null", null); + securityDeployer.loadPolicy(webModuleConfig.getDescriptor(), false); } catch (Throwable t) { logger.log(SEVERE, format(rb.getString(LOAD_WEB_MODULE_ERROR), webModuleConfig.getName()), t); } @@ -1829,22 +1838,20 @@ private WebModule loadWebModule(VirtualServer virtualServer, WebModuleConfig web boolean isSystem = resourceType != null && resourceType.startsWith("system-"); // Security will generate policy for system default web module - if (!webModuleName.startsWith(DEFAULT_WEB_MODULE_NAME)) { - // TODO : v3 : dochez Need to remove dependency on security - Realm realm = serviceLocator.getService(Realm.class); - if ("null".equals(j2eeApplication)) { - - // Standalone webapps inherit the realm referenced by the virtual server on which they are being deployed, unless they - // specify their own - if (realm != null && realm instanceof RealmInitializer) { - ((RealmInitializer) realm).initializeRealm(webBundleDescriptor, isSystem, virtualServer.getAuthRealmName()); - webModule.setRealm(realm); - } - } else { - if (realm != null && realm instanceof RealmInitializer) { - ((RealmInitializer) realm).initializeRealm(webBundleDescriptor, isSystem, null); - webModule.setRealm(realm); - } + // TODO : v3 : dochez Need to remove dependency on security + Realm realm = serviceLocator.getService(Realm.class); + if ("null".equals(j2eeApplication)) { + + // Standalone webapps inherit the realm referenced by the virtual server on which they are being deployed, unless they + // specify their own + if (realm != null && realm instanceof RealmInitializer) { + ((RealmInitializer) realm).initializeRealm(webBundleDescriptor, isSystem, virtualServer.getAuthRealmName()); + webModule.setRealm(realm); + } + } else { + if (realm != null && realm instanceof RealmInitializer) { + ((RealmInitializer) realm).initializeRealm(webBundleDescriptor, isSystem, null); + webModule.setRealm(realm); } } From 85f2fd00a71966d740fd6945977e04a10b51bbcb Mon Sep 17 00:00:00 2001 From: Alan Roth Date: Mon, 1 Apr 2019 11:41:17 +0100 Subject: [PATCH 093/108] Added missing quotation marks around description --- .../glassfish/admin/rest/resources/PropertiesBagResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/PropertiesBagResource.java b/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/PropertiesBagResource.java index b316a49f3a1..956f14faae7 100644 --- a/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/PropertiesBagResource.java +++ b/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/PropertiesBagResource.java @@ -184,7 +184,7 @@ protected ActionReportResult clearThenSaveProperties(List> p String unescapedValue = value.replaceAll("\\\\", ""); String description = null; - if (property.get(description) != null) { + if (property.get("description") != null) { description = Object.class.cast(property.get("description")).toString(); } From 14f175dafb64ab0e4112e902645b27ec69127fdb Mon Sep 17 00:00:00 2001 From: Alan Date: Mon, 1 Apr 2019 12:38:37 +0100 Subject: [PATCH 094/108] Updated copyright year From 2018 to 2019 --- .../glassfish/admin/rest/resources/PropertiesBagResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/PropertiesBagResource.java b/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/PropertiesBagResource.java index 956f14faae7..f2b76e01d33 100644 --- a/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/PropertiesBagResource.java +++ b/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/PropertiesBagResource.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2016-2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] package org.glassfish.admin.rest.resources; From ac2c485353af10233d3ce022646284f9416988de Mon Sep 17 00:00:00 2001 From: mertcaliskan Date: Wed, 30 Jan 2019 01:24:42 +0300 Subject: [PATCH 095/108] PAYARA-2965-Update-hk2-to-2.5.0 --- appserver/ejb/ejb-container/pom.xml | 4 +-- .../codegen/AsmSerializableBeanGenerator.java | 5 +-- .../ejb/codegen/EjbOptionalIntfGenerator.java | 26 +++++++------- .../pom.xml | 0 .../javaee-api/javax.javaee-web-api/pom.xml | 4 +-- .../security-oauth2/pom.xml | 6 ++-- appserver/pom.xml | 9 +++-- .../cli/schemadoc/AttributeMethodVisitor.java | 11 +++--- .../admin/cli/schemadoc/DocClassVisitor.java | 7 ++-- .../cli/schemadoc/GenerateDomainSchema.java | 5 +-- .../admin/rest/composite/CompositeUtil.java | 13 +++---- .../admin/rest/composite/Primitive.java | 5 +-- .../admin/rest/generator/ASMClassWriter.java | 13 +++---- nucleus/deployment/common/pom.xml | 4 +-- .../deployment/common/AnnotationScanner.java | 9 +++-- .../common/GenericAnnotationDetector.java | 34 +++++++++---------- .../glassfish/deployment/common/NodeInfo.java | 10 +++--- nucleus/flashlight/framework/pom.xml | 4 +-- .../impl/client/BtraceClientGenerator.java | 20 +++++------ .../ProbeProviderClassFileTransformer.java | 19 ++++++----- .../impl/core/ProviderImplGenerator.java | 14 ++++---- .../core/ProviderSubClassImplGenerator.java | 9 ++--- nucleus/packager/nucleus-hk2/pom.xml | 8 ++--- nucleus/pom.xml | 7 +--- 24 files changed, 125 insertions(+), 121 deletions(-) create mode 100644 appserver/extras/payara-micro/payara-micro-microprofile-distribution/pom.xml diff --git a/appserver/ejb/ejb-container/pom.xml b/appserver/ejb/ejb-container/pom.xml index 8237eaa4cfd..ef9b027389d 100755 --- a/appserver/ejb/ejb-container/pom.xml +++ b/appserver/ejb/ejb-container/pom.xml @@ -219,8 +219,8 @@ ${project.version} - org.glassfish.hk2.external - asm-repackaged + org.ow2.asm + asm-commons org.glassfish.pfl diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/AsmSerializableBeanGenerator.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/AsmSerializableBeanGenerator.java index d363ac43e50..c3137fe1900 100644 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/AsmSerializableBeanGenerator.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/AsmSerializableBeanGenerator.java @@ -37,10 +37,11 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016-2018] [Payara Foundation and/or its affiliates] +//Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] + package com.sun.ejb.codegen; -import org.glassfish.hk2.external.org.objectweb.asm.*; +import org.objectweb.asm.*; import java.io.Serializable; import java.lang.annotation.Annotation; diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/EjbOptionalIntfGenerator.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/EjbOptionalIntfGenerator.java index 925dde20662..6d9fee029ad 100644 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/EjbOptionalIntfGenerator.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/EjbOptionalIntfGenerator.java @@ -37,30 +37,30 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016] [Payara Foundation] +// Portions Copyright [2016-2019] Payara Foundation and/or affiliates + package com.sun.ejb.codegen; +import com.sun.ejb.spi.container.OptionalLocalInterfaceProvider; import com.sun.enterprise.container.common.spi.util.IndirectlySerializable; import com.sun.enterprise.container.common.spi.util.SerializableObjectFactory; -import com.sun.ejb.spi.container.OptionalLocalInterfaceProvider; +import com.sun.enterprise.deployment.util.TypeUtil; +import org.objectweb.asm.*; +import org.objectweb.asm.commons.GeneratorAdapter; +import org.objectweb.asm.commons.Method; +import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import java.lang.reflect.ReflectPermission; -import java.util.Map; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.io.Serializable; import java.security.AccessController; +import java.security.Permission; import java.security.PrivilegedAction; import java.security.ProtectionDomain; -import java.security.Permission; - -import com.sun.enterprise.deployment.util.TypeUtil; -import org.glassfish.hk2.external.org.objectweb.asm.*; -import org.glassfish.hk2.external.org.objectweb.asm.commons.GeneratorAdapter; -import org.glassfish.hk2.external.org.objectweb.asm.commons.Method; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; public class EjbOptionalIntfGenerator implements Opcodes { diff --git a/appserver/extras/payara-micro/payara-micro-microprofile-distribution/pom.xml b/appserver/extras/payara-micro/payara-micro-microprofile-distribution/pom.xml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/appserver/javaee-api/javax.javaee-web-api/pom.xml b/appserver/javaee-api/javax.javaee-web-api/pom.xml index e363869e7ef..9d027c1dbbc 100644 --- a/appserver/javaee-api/javax.javaee-web-api/pom.xml +++ b/appserver/javaee-api/javax.javaee-web-api/pom.xml @@ -203,8 +203,8 @@ true - javax.inject - javax.inject + org.glassfish.hk2.external + jakarta.inject true diff --git a/appserver/payara-appserver-modules/security-oauth2/pom.xml b/appserver/payara-appserver-modules/security-oauth2/pom.xml index 32ea6e561db..75135af1201 100644 --- a/appserver/payara-appserver-modules/security-oauth2/pom.xml +++ b/appserver/payara-appserver-modules/security-oauth2/pom.xml @@ -2,7 +2,7 @@ - 1 2.0.SP1 3.1.0.Final 3.1.0.Final @@ -271,7 +270,7 @@ 1.2

    ${stage.dir}/${install.dir.name}/glassfish/modules - javax.inject.jar,javax.servlet.jsp.jstl.jar,javax.servlet.jsp.jar,javax.enterprise.concurrent.jar, javax.persistence.jar + jakarta.inject.jar,javax.servlet.jsp.jstl.jar,javax.servlet.jsp.jar,javax.enterprise.concurrent.jar, javax.persistence.jar @@ -652,9 +651,9 @@ ${cdi-api.version} - javax.inject - javax.inject - ${javax.inject.version} + org.glassfish.hk2.external + jakarta.inject + ${hk2.version} javax.resource diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/AttributeMethodVisitor.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/AttributeMethodVisitor.java index b9c24db7ba2..eea242ca8c5 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/AttributeMethodVisitor.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/AttributeMethodVisitor.java @@ -37,14 +37,15 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016] [Payara Foundation] +//Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] + package com.sun.enterprise.admin.cli.schemadoc; import org.glassfish.api.admin.config.PropertiesDesc; import org.glassfish.api.admin.config.PropertyDesc; -import org.glassfish.hk2.external.org.objectweb.asm.AnnotationVisitor; -import org.glassfish.hk2.external.org.objectweb.asm.MethodVisitor; -import org.glassfish.hk2.external.org.objectweb.asm.Opcodes; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; import org.jvnet.hk2.config.Attribute; public class AttributeMethodVisitor extends MethodVisitor { @@ -54,7 +55,7 @@ public class AttributeMethodVisitor extends MethodVisitor { private boolean duckTyped; public AttributeMethodVisitor(ClassDef classDef, String method, String aggType) { - super(Opcodes.ASM5); + super(Opcodes.ASM7); def = classDef; name = method; type = aggType; diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/DocClassVisitor.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/DocClassVisitor.java index 5536546b637..bac47078a5b 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/DocClassVisitor.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/DocClassVisitor.java @@ -37,14 +37,15 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016] [Payara Foundation] +//Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] package com.sun.enterprise.admin.cli.schemadoc; +import org.objectweb.asm.*; + import java.util.ArrayList; import java.util.List; -import org.glassfish.hk2.external.org.objectweb.asm.*; public class DocClassVisitor extends ClassVisitor { private boolean hasConfiguredAnnotation = false; @@ -54,7 +55,7 @@ public class DocClassVisitor extends ClassVisitor { private boolean showDeprecated; public DocClassVisitor(final boolean showDep) { - super(Opcodes.ASM5); + super(Opcodes.ASM7); showDeprecated = showDep; } diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/GenerateDomainSchema.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/GenerateDomainSchema.java index 1b1a684683c..afedd1d589c 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/GenerateDomainSchema.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/GenerateDomainSchema.java @@ -37,7 +37,8 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016] [Payara Foundation] +//Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] + package com.sun.enterprise.admin.cli.schemadoc; import java.io.File; @@ -60,7 +61,7 @@ import org.glassfish.config.support.TargetType; import org.glassfish.hk2.api.ServiceLocator; -import org.glassfish.hk2.external.org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassReader; import org.jvnet.hk2.annotations.Service; import org.glassfish.hk2.api.PerLookup; diff --git a/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/composite/CompositeUtil.java b/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/composite/CompositeUtil.java index 6955d71b511..14a5c31789c 100644 --- a/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/composite/CompositeUtil.java +++ b/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/composite/CompositeUtil.java @@ -37,7 +37,8 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016-2017] [Payara Foundation and/or affiliates] +//Portions Copyright [2016-2019] [Payara Foundation and/or affiliates] + package org.glassfish.admin.rest.composite; import com.sun.enterprise.util.LocalStringManagerImpl; @@ -98,10 +99,10 @@ import org.glassfish.api.ActionReport.ExitCode; import org.glassfish.api.admin.ParameterMap; import org.glassfish.hk2.api.ActiveDescriptor; -import org.glassfish.hk2.external.org.objectweb.asm.AnnotationVisitor; -import org.glassfish.hk2.external.org.objectweb.asm.ClassWriter; -import org.glassfish.hk2.external.org.objectweb.asm.FieldVisitor; -import org.glassfish.hk2.external.org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; import org.glassfish.hk2.utilities.BuilderHelper; import org.glassfish.internal.api.Globals; import org.glassfish.jersey.media.sse.EventOutput; @@ -941,7 +942,7 @@ private void createGettersAndSetters(ClassWriter cw, Class c, String className, final String paramName = values.getKey(); Object paramValue = values.getValue(); if (Class.class.isAssignableFrom(paramValue.getClass())) { - paramValue = org.glassfish.hk2.external.org.objectweb.asm.Type.getType("L" + getInternalName(paramValue.getClass().getName()) + ";"); + paramValue = org.objectweb.asm.Type.getType("L" + getInternalName(paramValue.getClass().getName()) + ";"); } if (paramValue.getClass().isArray() && (Array.getLength(paramValue) == 0)) { continue; diff --git a/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/composite/Primitive.java b/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/composite/Primitive.java index efa3f4380ec..0c9e7719c29 100644 --- a/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/composite/Primitive.java +++ b/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/composite/Primitive.java @@ -37,10 +37,11 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016] [Payara Foundation] +//Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] + package org.glassfish.admin.rest.composite; -import static org.glassfish.hk2.external.org.objectweb.asm.Opcodes.*; +import static org.objectweb.asm.Opcodes.*; /** * This enum encapsulates the metadata for primitives needed for generating fields, getters and setters diff --git a/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/generator/ASMClassWriter.java b/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/generator/ASMClassWriter.java index e4f9bcfeb60..667bb37a4d6 100644 --- a/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/generator/ASMClassWriter.java +++ b/nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/generator/ASMClassWriter.java @@ -37,7 +37,8 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016-2017] [Payara Foundation] +//Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] + package org.glassfish.admin.rest.generator; import com.sun.enterprise.util.SystemPropertyConstants; @@ -52,10 +53,10 @@ import org.glassfish.admin.rest.RestLogging; import org.glassfish.admin.rest.utils.ResourceUtil; import org.glassfish.hk2.api.ServiceLocator; -import org.glassfish.hk2.external.org.objectweb.asm.AnnotationVisitor; -import org.glassfish.hk2.external.org.objectweb.asm.MethodVisitor; -import org.glassfish.hk2.external.org.objectweb.asm.Opcodes; -import org.glassfish.hk2.external.org.objectweb.asm.Type; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; /** * @author Ludovic Champenois @@ -67,7 +68,7 @@ public class ASMClassWriter implements ClassWriter, Opcodes { private final static String CREATE_AND_INITIALIZE = "createAndInitialize"; private final static String CREATE_AND_INITIALIZE_SIG = "(Ljava/lang/Class;)Ljava/lang/Object;"; - private org.glassfish.hk2.external.org.objectweb.asm.ClassWriter cw = new org.glassfish.hk2.external.org.objectweb.asm.ClassWriter(0); + private org.objectweb.asm.ClassWriter cw = new org.objectweb.asm.ClassWriter(0); private String className; private ServiceLocator habitat; private final String generatedPath; diff --git a/nucleus/deployment/common/pom.xml b/nucleus/deployment/common/pom.xml index 838b61d3a7b..7c396008560 100755 --- a/nucleus/deployment/common/pom.xml +++ b/nucleus/deployment/common/pom.xml @@ -128,8 +128,8 @@ ${project.version} - org.glassfish.hk2.external - asm-repackaged + org.ow2.asm + asm-commons org.glassfish.main.tests diff --git a/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/AnnotationScanner.java b/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/AnnotationScanner.java index c575d094c7d..f90a67aadc8 100644 --- a/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/AnnotationScanner.java +++ b/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/AnnotationScanner.java @@ -37,10 +37,11 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016] [Payara Foundation] +//Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] + package org.glassfish.deployment.common; -import org.glassfish.hk2.external.org.objectweb.asm.*; +import org.objectweb.asm.*; import java.io.InputStream; import java.io.File; @@ -55,6 +56,8 @@ import org.glassfish.api.deployment.archive.ReadableArchive; import org.glassfish.logging.annotation.LogMessageInfo; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Opcodes; public class AnnotationScanner extends ClassVisitor { @@ -70,7 +73,7 @@ public class AnnotationScanner extends ClassVisitor { private static final String FAILED_ANNOTATION_SCAN = "NCLS-DEPLOYMENT-00003"; public AnnotationScanner() { - super(Opcodes.ASM5); + super(Opcodes.ASM7); } public void visit(int version, diff --git a/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/GenericAnnotationDetector.java b/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/GenericAnnotationDetector.java index 8d7466e75f4..17b9fbecae5 100644 --- a/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/GenericAnnotationDetector.java +++ b/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/GenericAnnotationDetector.java @@ -37,31 +37,29 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016-2017] [Payara Foundation] +//Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] + package org.glassfish.deployment.common; -import java.io.FileNotFoundException; -import java.util.List; -import java.util.ArrayList; +import com.sun.enterprise.deploy.shared.ArchiveFactory; +import org.glassfish.api.deployment.archive.ReadableArchive; +import org.glassfish.internal.api.Globals; +import org.glassfish.logging.annotation.LogMessageInfo; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.Type; -import java.io.InputStream; import java.io.File; -import java.io.IOException; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.net.URI; +import java.util.ArrayList; import java.util.Enumeration; -import java.util.logging.Logger; -import java.util.logging.LogRecord; +import java.util.List; import java.util.logging.Level; -import java.net.URI; - -import org.glassfish.api.deployment.archive.ReadableArchive; -import com.sun.enterprise.deploy.shared.ArchiveFactory; -import org.glassfish.hk2.external.org.objectweb.asm.AnnotationVisitor; -import org.glassfish.hk2.external.org.objectweb.asm.ClassReader; -import org.glassfish.hk2.external.org.objectweb.asm.Type; -import org.glassfish.internal.api.Globals; - -import org.glassfish.logging.annotation.LogMessageInfo; +import java.util.logging.LogRecord; +import java.util.logging.Logger; /** * This class will detect whether an archive contains specified annotations. diff --git a/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/NodeInfo.java b/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/NodeInfo.java index 57988efab61..8839311f313 100644 --- a/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/NodeInfo.java +++ b/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/NodeInfo.java @@ -37,10 +37,12 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016] [Payara Foundation] +//Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] + package org.glassfish.deployment.common; -import org.glassfish.hk2.external.org.objectweb.asm.*; + +import org.objectweb.asm.*; import java.util.List; import java.util.ArrayList; @@ -89,7 +91,7 @@ class NodeInfo private static final Set EMPTY_NODEINFO_SET = new HashSet(); NodeInfo(byte[] classData) { - super(Opcodes.ASM5); + super(Opcodes.ASM7); ClassReader cr = new ClassReader(classData); cr.accept(this, ClassReader.SKIP_CODE); @@ -137,7 +139,7 @@ void markAsEnumType() { } NodeInfo(String className) { - super(Opcodes.ASM5); + super(Opcodes.ASM7); this.className = className; } diff --git a/nucleus/flashlight/framework/pom.xml b/nucleus/flashlight/framework/pom.xml index afe27649874..c7d5cb9199a 100755 --- a/nucleus/flashlight/framework/pom.xml +++ b/nucleus/flashlight/framework/pom.xml @@ -111,8 +111,8 @@ provided - org.glassfish.hk2.external - asm-repackaged + org.ow2.asm + asm-commons diff --git a/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/client/BtraceClientGenerator.java b/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/client/BtraceClientGenerator.java index f78111b228b..c5f17fa89ae 100644 --- a/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/client/BtraceClientGenerator.java +++ b/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/client/BtraceClientGenerator.java @@ -37,7 +37,8 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016] [Payara Foundation] +// Portions Copyright [2016-2019] Payara Foundation and/or affiliates + package org.glassfish.flashlight.impl.client; /** @@ -45,22 +46,19 @@ * Started: Jul 20, 2008 * @author Byron Nevins, August 2009 */ + import com.sun.enterprise.util.SystemPropertyConstants; import org.glassfish.flashlight.provider.FlashlightProbe; import org.glassfish.flashlight.provider.ProbeRegistry; -import org.glassfish.hk2.external.org.objectweb.asm.AnnotationVisitor; -import org.glassfish.hk2.external.org.objectweb.asm.ClassWriter; -import org.glassfish.hk2.external.org.objectweb.asm.Opcodes; -import org.glassfish.hk2.external.org.objectweb.asm.Type; -import org.glassfish.hk2.external.org.objectweb.asm.commons.GeneratorAdapter; -import org.glassfish.hk2.external.org.objectweb.asm.commons.Method; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.GeneratorAdapter; +import org.objectweb.asm.commons.Method; import java.io.File; import java.io.FileOutputStream; -import java.io.PrintStream; -import java.lang.reflect.InvocationTargetException; -import java.security.PrivilegedActionException; -import java.security.ProtectionDomain; import java.util.Collection; public class BtraceClientGenerator { diff --git a/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/client/ProbeProviderClassFileTransformer.java b/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/client/ProbeProviderClassFileTransformer.java index 39a49f14845..38e28617c25 100644 --- a/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/client/ProbeProviderClassFileTransformer.java +++ b/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/client/ProbeProviderClassFileTransformer.java @@ -37,7 +37,8 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016] [Payara Foundation] +// Portions Copyright [2016-2019] Payara Foundation and/or affiliates + package org.glassfish.flashlight.impl.client; import com.sun.enterprise.util.SystemPropertyConstants; @@ -63,8 +64,8 @@ import org.glassfish.flashlight.provider.FlashlightProbe; import org.glassfish.flashlight.provider.ProbeRegistry; -import org.glassfish.hk2.external.org.objectweb.asm.*; -import org.glassfish.hk2.external.org.objectweb.asm.commons.AdviceAdapter; +import org.objectweb.asm.*; +import org.objectweb.asm.commons.AdviceAdapter; /** * July 2012 Byron Nevins says: We no longer allow outsiders to create @@ -310,7 +311,7 @@ private class ProbeProviderClassVisitor extends ClassVisitor { ProbeProviderClassVisitor(ClassVisitor cv) { - super(Opcodes.ASM5, cv); + super(Opcodes.ASM7, cv); if (Log.getLogger().isLoggable(Level.FINER)) { for (String methodDesc : probes.keySet()) { Log.finer("visit" + methodDesc); @@ -339,7 +340,7 @@ private static class ProbeProviderMethodVisitor private Label startFinally; ProbeProviderMethodVisitor(MethodVisitor mv, int access, String name, String desc, FlashlightProbe probe) { - super(Opcodes.ASM5, mv, access, name, desc); + super(Opcodes.ASM7, mv, access, name, desc); this.probe = probe; } @@ -383,7 +384,7 @@ protected void onMethodEnter() { loadArgArray(); invokeStatic(Type.getType( ProbeRegistry.class), - org.glassfish.hk2.external.org.objectweb.asm.commons.Method.getMethod( + org.objectweb.asm.commons.Method.getMethod( "Object invokeProbeBefore(int, Object[])")); // Store return to local @@ -420,7 +421,7 @@ private void onFinally(int opcode) { // Push the state from the local loadLocal(stateLocal); invokeStatic(Type.getType(ProbeRegistry.class), - org.glassfish.hk2.external.org.objectweb.asm.commons.Method.getMethod( + org.objectweb.asm.commons.Method.getMethod( "void invokeProbeOnException(Object, int, Object)")); } else { @@ -452,7 +453,7 @@ private void onFinally(int opcode) { // Push the state from the local loadLocal(stateLocal); invokeStatic(Type.getType(ProbeRegistry.class), - org.glassfish.hk2.external.org.objectweb.asm.commons.Method.getMethod( + org.objectweb.asm.commons.Method.getMethod( "void invokeProbeAfter(Object, int, Object)")); } } @@ -464,7 +465,7 @@ private void insertCode() { loadArgArray(); invokeStatic(Type.getType( ProbeRegistry.class), - org.glassfish.hk2.external.org.objectweb.asm.commons.Method.getMethod("void invokeProbe(int, Object[])")); + org.objectweb.asm.commons.Method.getMethod("void invokeProbe(int, Object[])")); } } diff --git a/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/core/ProviderImplGenerator.java b/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/core/ProviderImplGenerator.java index 585c89eca57..df9c2f98b75 100644 --- a/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/core/ProviderImplGenerator.java +++ b/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/core/ProviderImplGenerator.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2016-2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] package org.glassfish.flashlight.impl.core; @@ -51,12 +51,12 @@ import org.glassfish.flashlight.FlashlightLoggerInfo; import org.glassfish.flashlight.provider.FlashlightProbe; import org.glassfish.flashlight.provider.ProbeRegistry; -import org.glassfish.hk2.external.org.objectweb.asm.ClassWriter; -import org.glassfish.hk2.external.org.objectweb.asm.Label; -import org.glassfish.hk2.external.org.objectweb.asm.Opcodes; -import org.glassfish.hk2.external.org.objectweb.asm.Type; -import org.glassfish.hk2.external.org.objectweb.asm.commons.GeneratorAdapter; -import org.glassfish.hk2.external.org.objectweb.asm.commons.Method; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.GeneratorAdapter; +import org.objectweb.asm.commons.Method; import java.io.File; import java.io.FileOutputStream; diff --git a/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/core/ProviderSubClassImplGenerator.java b/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/core/ProviderSubClassImplGenerator.java index f8b6e7e1ee0..f07dd53b70b 100644 --- a/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/core/ProviderSubClassImplGenerator.java +++ b/nucleus/flashlight/framework/src/main/java/org/glassfish/flashlight/impl/core/ProviderSubClassImplGenerator.java @@ -37,7 +37,8 @@ * only if the new code is made subject to such option by the copyright * holder. */ -//Portions Copyright [2016] [Payara Foundation] +//Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] + package org.glassfish.flashlight.impl.core; /** @@ -47,7 +48,7 @@ */ import com.sun.enterprise.util.LocalStringManagerImpl; import org.glassfish.flashlight.FlashlightLoggerInfo; -import org.glassfish.hk2.external.org.objectweb.asm.*; +import org.objectweb.asm.*; import java.security.*; @@ -161,7 +162,7 @@ private static class ProbeProviderSubClassGenerator String id; ProbeProviderSubClassGenerator(ClassVisitor cv, String token, String id) { - super(Opcodes.ASM5, cv); + super(Opcodes.ASM7, cv); this.id = id; this.token = token; } @@ -209,7 +210,7 @@ private static class ProbeProviderAnnotationVisitor private String token; ProbeProviderAnnotationVisitor(AnnotationVisitor delegate, String token) { - super(Opcodes.ASM5); + super(Opcodes.ASM7); this.delegate = delegate; this.token = token; } diff --git a/nucleus/packager/nucleus-hk2/pom.xml b/nucleus/packager/nucleus-hk2/pom.xml index 26491bedda9..3d58a551c42 100644 --- a/nucleus/packager/nucleus-hk2/pom.xml +++ b/nucleus/packager/nucleus-hk2/pom.xml @@ -40,7 +40,7 @@ holder. --> - + 4.0.0 @@ -97,11 +97,11 @@ org.glassfish.hk2.external - javax.inject + jakarta.inject - org.glassfish.hk2.external - asm-repackaged + org.ow2.asm + asm-commons org.glassfish.hk2.external diff --git a/nucleus/pom.xml b/nucleus/pom.xml index b18bfb51010..fc8b714bae0 100644 --- a/nucleus/pom.xml +++ b/nucleus/pom.xml @@ -290,7 +290,7 @@ - 2.5.0-b61.payara-p1 + 2.5.0 2.5.0-b61.payara-p2 @@ -1357,11 +1357,6 @@ Parent is ${project.parent} hawtjni-runtime 1.13 - - org.glassfish.hk2.external - asm-repackaged - ${hk2.version} - org.javassist javassist From aa3bfbbe2efee692e20be0f011184ed30ed31381 Mon Sep 17 00:00:00 2001 From: mertcaliskan Date: Sun, 17 Mar 2019 23:10:41 +0300 Subject: [PATCH 096/108] PAYARA-2965-Update-hk2-to-2.5.0 - javax.inject is now -> jakarta.inject - removed asm-repackaged since asm is now being used directly - moved onto hk2 version 2.5.0.payara-p1 --- .../com/sun/enterprise/registration/glassfish/ModuleMap.java | 2 +- .../felix/src/main/resources/config/osgi.properties | 5 ++--- nucleus/pom.xml | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/appserver/registration/glassfish-registration/src/main/java/com/sun/enterprise/registration/glassfish/ModuleMap.java b/appserver/registration/glassfish-registration/src/main/java/com/sun/enterprise/registration/glassfish/ModuleMap.java index 2389839a019..6e1cdaded27 100644 --- a/appserver/registration/glassfish-registration/src/main/java/com/sun/enterprise/registration/glassfish/ModuleMap.java +++ b/appserver/registration/glassfish-registration/src/main/java/com/sun/enterprise/registration/glassfish/ModuleMap.java @@ -159,7 +159,7 @@ public class ModuleMap { put("org.glassfish.hk2.config", 100); put("org.glassfish.hk2.config-types", 101); put("org.glassfish.hk2.core", 102); - put("org.glassfish.hk2.external.asm-repackaged", 103); + //put("org.glassfish.hk2.external.asm-repackaged", 103); //put("org.glassfish.hk2.external.bean-validator", 104); put("org.glassfish.hk2.hk2", 105); put("org.glassfish.hk2.osgi-adapter", 106); diff --git a/nucleus/osgi-platforms/felix/src/main/resources/config/osgi.properties b/nucleus/osgi-platforms/felix/src/main/resources/config/osgi.properties index 385813f71b3..20bc8795bbf 100755 --- a/nucleus/osgi-platforms/felix/src/main/resources/config/osgi.properties +++ b/nucleus/osgi-platforms/felix/src/main/resources/config/osgi.properties @@ -56,7 +56,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# Portions Copyright [2017-2018] [Payara Foundation and/or its affiliates] +# Portions Copyright [2017-2019] [Payara Foundation and/or its affiliates] # # Framework config properties. @@ -186,14 +186,13 @@ glassfish.osgi.auto.install=\ hk2.bundles=\ ${com.sun.aas.installRootURI}modules/hk2-api.jar \ ${com.sun.aas.installRootURI}modules/hk2-utils.jar \ - ${com.sun.aas.installRootURI}modules/javax.inject.jar \ + ${com.sun.aas.installRootURI}modules/jakarta.inject.jar \ ${com.sun.aas.installRootURI}modules/osgi-resource-locator.jar \ ${com.sun.aas.installRootURI}modules/hk2-locator.jar \ ${com.sun.aas.installRootURI}modules/hk2-runlevel.jar \ ${com.sun.aas.installRootURI}modules/hk2-config.jar \ ${com.sun.aas.installRootURI}modules/config-types.jar \ ${com.sun.aas.installRootURI}modules/class-model.jar \ - ${com.sun.aas.installRootURI}modules/asm-repackaged.jar \ ${com.sun.aas.installRootURI}modules/osgi-adapter.jar core.bundles=\ diff --git a/nucleus/pom.xml b/nucleus/pom.xml index fc8b714bae0..458a9217c26 100644 --- a/nucleus/pom.xml +++ b/nucleus/pom.xml @@ -290,7 +290,7 @@ - 2.5.0 + 2.5.0.payara-p1 2.5.0-b61.payara-p2 From 74bf424b9188c165ea2e4166a41e9f19ad2260c9 Mon Sep 17 00:00:00 2001 From: mertcaliskan Date: Thu, 21 Mar 2019 00:37:28 +0300 Subject: [PATCH 097/108] PAYARA-2965-Update-hk2-to-2.5.0 using prefixed groupId of tiger-types --- nucleus/hk2/hk2-config/pom.xml | 2 +- nucleus/packager/nucleus-hk2/pom.xml | 7 ++++++- nucleus/pom.xml | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/nucleus/hk2/hk2-config/pom.xml b/nucleus/hk2/hk2-config/pom.xml index 4cbf0d460c7..19bf349ba0a 100644 --- a/nucleus/hk2/hk2-config/pom.xml +++ b/nucleus/hk2/hk2-config/pom.xml @@ -141,7 +141,7 @@ org.jvnet tiger-types - 1.4 + ${tiger.types.version} org.hibernate.validator diff --git a/nucleus/packager/nucleus-hk2/pom.xml b/nucleus/packager/nucleus-hk2/pom.xml index 3d58a551c42..cee62f552b2 100644 --- a/nucleus/packager/nucleus-hk2/pom.xml +++ b/nucleus/packager/nucleus-hk2/pom.xml @@ -139,7 +139,12 @@ javassist ${javassist.version} - + + + org.jvnet + tiger-types + ${tiger.types.version} + diff --git a/nucleus/pom.xml b/nucleus/pom.xml index 458a9217c26..bcfa9db4918 100644 --- a/nucleus/pom.xml +++ b/nucleus/pom.xml @@ -289,10 +289,11 @@ - 2.5.0.payara-p1 2.5.0-b61.payara-p2 + 1.4.payara-p1 + 4.1.1.payara-p1 1.0-2 From 997fec45e4660227d37c3af6db98683e296f9ce5 Mon Sep 17 00:00:00 2001 From: mertcaliskan Date: Tue, 2 Apr 2019 00:15:36 +0300 Subject: [PATCH 098/108] PAYARA-2965-Update-hk2-to-2.5.0 upgrade hk2 plugins version --- nucleus/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nucleus/pom.xml b/nucleus/pom.xml index bcfa9db4918..f603fa0a08f 100644 --- a/nucleus/pom.xml +++ b/nucleus/pom.xml @@ -290,7 +290,7 @@ 2.5.0.payara-p1 - 2.5.0-b61.payara-p2 + 2.5.0.payara-p1 1.4.payara-p1 From f3753b020ddd49cb2db36ecc96f2a1a1cedf94c7 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 2 Apr 2019 10:09:04 +0200 Subject: [PATCH 099/108] PAYARA-3466 addressed some of Matt's PR comments --- .../openapi/impl/model/media/SchemaImpl.java | 2 +- .../impl/model/util/AnnotationInfo.java | 93 ++++++++++++++++++- .../impl/processor/ApplicationProcessor.java | 14 ++- .../openapi/impl/visitor/OpenApiWalker.java | 1 - .../app/application/SchemaReferenceTest.java | 2 +- 5 files changed, 100 insertions(+), 12 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java index 5f8e4e52a52..a076cb26bd1 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/media/SchemaImpl.java @@ -357,7 +357,7 @@ public void removeProperty(String key) { this.properties.remove(key); } - @JsonProperty("additionalProperties") + @JsonProperty @Override public Object getAdditionalProperties() { return additionalProperties; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java index 1ce7ed8312e..907f1e51981 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/AnnotationInfo.java @@ -50,7 +50,8 @@ /** * Represents the aggregated annotations on a type, its fields and methods including annotations "inherited" from - * super-classes and implemented interfaces. + * super-classes and implemented interfaces. Should a field or method from a super-class be overridden the + * {@link Annotation} closest to the represented type (the overriding one) is kept. */ public final class AnnotationInfo { @@ -76,26 +77,67 @@ public Class getType() { return type; } + /** + * Version of {@link Class#getAnnotation(Class)} also considering annotations "inherited" from + * super-types for this {@link AnnotationInfo#getType()}. + * + * @param annotationType annotation type to check + * @return the annotation of the given type if present or {@code null} otherwise + */ @SuppressWarnings("unchecked") public A getAnnotation(Class annotationType) { return (A) typeAnnotations.get(annotationType); } + /** + * Version of {@link Field#getAnnotation(Class)} also considering annotations "inherited" from overridden fields + * of super-types. + * + * @param annotationType annotation type to check + * @param method must be a {@link Field} defined or inherited by this {@link AnnotationInfo#getType()} + * @return the annotation of the given type if present or {@code null} otherwise + */ @SuppressWarnings("unchecked") public A getAnnotation(Class annotationType, Field field) { return (A) fieldAnnotations.get(field.getName()).get(annotationType); } + /** + * Version of {@link Method#getAnnotation(Class)} also considering annotations "inherited" from overridden methods + * of super-types. + * + * @param annotationType annotation type to check + * @param method must be a {@link Method} defined or inherited by this {@link AnnotationInfo#getType()} + * @return the annotation of the given type if present or {@code null} otherwise + */ @SuppressWarnings("unchecked") public A getAnnotation(Class annotationType, Method method) { return (A) methodAnnotations.get(getSignature(method)).get(annotationType); } + /** + * Version of {@link Parameter#getAnnotation(Class)} also considering annotations "inherited" from overridden + * methods of super-types. + * + * @param annotationType annotation type to check + * @param parameter must be this a {@link Parameter} of a {@link Method} defined or inherited by this + * {@link AnnotationInfo#getType()} + * @return the annotation of the given type if present or {@code null} otherwise + */ @SuppressWarnings("unchecked") public A getAnnotation(Class annotationType, Parameter parameter) { return (A) methodParameterAnnotations.get(getIdentifier(parameter)).get(annotationType); } + /** + * Version of {@link AnnotatedElement#getAnnotation(Class)} also considering annotations "inherited" from + * super-types. + * + * @param annotationType annotation type to check + * @param element must be this {@link AnnotationInfo#getType()}'s {@link Class} or a {@link Field} or + * {@link Method} defined or inherited by it or a {@link Parameter} of such a method. + * @return the annotation of the given type if present or {@code null} otherwise + */ public A getAnnotation(Class annotationType, AnnotatedElement element) { Class kind = element.getClass(); if (kind == Class.class) { @@ -113,26 +155,67 @@ public A getAnnotation(Class annotationType, Annotated return null; } + /** + * Version of {@link Class#isAnnotationPresent(Class)} also considering annotations "inherited" from super-types. + * + * @param annotationType annotation type to check + * @return true in case it is present at this class or any of its super-types + */ public boolean isAnnotationPresent(Class annotationType) { return getAnnotation(annotationType) != null; } + /** + * Version of {@link Field#isAnnotationPresent(Class)} also considering annotations "inherited" from super-types. + * + * @param annotationType annotation type to check + * @return true in case it is present at the given field. The field must be defined in this + * {@link AnnotationInfo#getType()} or any of its super-types. + */ public boolean isAnnotationPresent(Class annotationType, Field field) { return getAnnotation(annotationType, field) != null; } + /** + * Version of {@link Method#isAnnotationPresent(Class)} also considering annotations "inherited" from super-types. + * + * @param annotationType annotation type to check + * @param method the method checked for annotation. The method must be defined or inherited by this + * {@link AnnotationInfo#getType()} or any of its super-types. + * @return true in case it is present at the given method, else false + */ public boolean isAnnotationPresent(Class annotationType, Method method) { return getAnnotation(annotationType, method) != null; } + /** + * Version of {@link Parameter#isAnnotationPresent(Class)} also considering annotations "inherited" from super-types. + * + * @param annotationType annotation type to check + * @param parameter the parameter checked for annotations. The parameter must belong to a method defined or + * inherited by this {@link AnnotationInfo#getType()} + * @return true in case it is present at the given parameter, else false + */ public boolean isAnnotationPresent(Class annotationType, Parameter parameter) { return getAnnotation(annotationType, parameter) != null; } + /** + * Version of {@link AnnotatedElement#isAnnotationPresent(Class)} also considering annotations "inherited" from + * super-types. + * + * @param annotationType annotation type to check + * @param element must be this {@link AnnotationInfo#getType()}'s {@link Class} or a {@link Field} or + * {@link Method} defined or inherited by it or a {@link Parameter} of such a method. + * @return true in case it is present at the given element, else false + */ public boolean isAnnotationPresent(Class annotationType, AnnotatedElement element) { return getAnnotation(annotationType, element) != null; } + /** + * @see #isAnnotationPresent(Class, AnnotatedElement) + */ @SafeVarargs public final boolean isAnyAnnotationPresent(AnnotatedElement element, Class... annotationTypes) { for (Class annotationType : annotationTypes) { @@ -143,6 +226,14 @@ public final boolean isAnyAnnotationPresent(AnnotatedElement element, Class> classes; - + /** * @param appClassLoader the class loader for the application. */ public ApplicationProcessor(Set> appClasses) { this.classes = appClasses; this.classes.removeIf(cls -> cls.isInterface() || Modifier.isAbstract(cls.getModifiers())); - if (classes != null) { - addInnerClasses(); - } + addInnerClasses(); } private void addInnerClasses() { @@ -175,7 +173,7 @@ private void addInnerClasses(Class topLevelClass) { } } } - + @Override public OpenAPI process(OpenAPI api, OpenApiConfiguration config) { ApiWalker apiWalker = null; @@ -460,10 +458,10 @@ private void addParameter(AnnotatedElement element, ApiContext context, String defaultValue = getDefaultValueIfPresent(element); if (element instanceof java.lang.reflect.Parameter) { - java.lang.reflect.Parameter parameter = java.lang.reflect.Parameter.class.cast(element); + java.lang.reflect.Parameter parameter = (java.lang.reflect.Parameter) element; schema.setType(ModelUtils.getSchemaType(parameter.getType())); } else { - Field field = Field.class.cast(element); + Field field = (Field) element; schema.setType(ModelUtils.getSchemaType(field.getType())); } @@ -482,7 +480,7 @@ private void addParameter(AnnotatedElement element, ApiContext context, context.getWorkingOperation().addParameter(newParameter); } else { if (element instanceof Field) { - Field field = Field.class.cast(element); + Field field = (Field) element; ApiContext apiContext; OpenAPI api = context.getApi(); for (Method method : field.getDeclaringClass().getDeclaredMethods()) { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java index 251f9605c12..4c9ea3d59d8 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java @@ -153,7 +153,6 @@ public void accept(ApiVisitor visitor) { processAnnotations(FormParam.class, visitor::visitFormParam); // All other OpenAPI annotations - processAnnotations(Schema.class, visitor::visitSchema); processAnnotations(Server.class, visitor::visitServer, Servers.class); processAnnotations(Servers.class, visitor::visitServers, Server.class); processAnnotations(Extensions.class, visitor::visitExtensions, Extension.class); diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaReferenceTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaReferenceTest.java index 71d6b2f6073..14d784da18e 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaReferenceTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaReferenceTest.java @@ -92,7 +92,7 @@ public List getServers() { } @Test - public void test() { + public void annotatedServerSchemaIsReferenced() { JsonNode items = path(getOpenAPIJson(), "paths./test/servers.get.responses.default.content.application/json.schema.items"); assertNotNull(items); From eb796170fe34c8d6186895fee78a4255838087c4 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 2 Apr 2019 10:15:05 +0200 Subject: [PATCH 100/108] PAYARA-3466 warn about non-conformant extension names but don't correct them --- .../microprofile/openapi/impl/model/ExtensibleImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index 05fd42caed5..afb4c7ec765 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -92,7 +92,11 @@ public void setExtensions(Map extensions) { } public static String extensionName(String name) { - return name.startsWith("x-") ? name : "x-" + name; + if (name != null && !name.startsWith("x-")) { + //NB. MP group decided that extension names should not be corrected + LOGGER.warning("extension name not starting with `x-` cause invalid Open API documents: " + name); + } + return name; } public static void merge(Extension from, Extensible to, boolean override) { From adb1741a51440ba23c151658c3b8150d126f3a35 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 2 Apr 2019 13:03:51 +0200 Subject: [PATCH 101/108] PAYARA-3466 fixed: processing Schema annotation after HTTP method annotations --- .../openapi/impl/visitor/OpenApiWalker.java | 2 +- .../app/application/SchemaExampleTest.java | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaExampleTest.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java index 4c9ea3d59d8..0addc8f87df 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java @@ -134,7 +134,6 @@ public OpenApiWalker(OpenAPI api, Set> allowedClasses, Map Date: Tue, 2 Apr 2019 16:09:12 +0200 Subject: [PATCH 102/108] PAYARA-3466 replaced .cast() with (Type) cast, cleaned and added tests for #isAnnotationNull --- .../openapi/impl/model/util/ModelUtils.java | 55 +++++---- .../impl/processor/ApplicationProcessor.java | 6 +- .../impl/model/util/ModelUtilsTest.java | 109 ++++++++++++++++++ 3 files changed, 138 insertions(+), 32 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java index fa10e7d3a28..b8c4718ee35 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtils.java @@ -375,27 +375,21 @@ public static boolean isAnnotationNull(Annotation annotation) { if (m.getParameterCount() == 0) { try { Object value = m.invoke(annotation); - if (value != null) { - if (value.getClass().isArray() && Array.getLength(value) > 0) { - return false; - } else if (value instanceof Collection && !Collection.class.cast(value).isEmpty()) { - return false; - } else if (value instanceof Boolean && ((Boolean)value).booleanValue()) { - return false; - } else if (value.getClass().equals(Class.class) - && !Class.class.cast(value).getTypeName().equals("java.lang.Void")) { - return false; - } else if (value.getClass().isEnum() && !Enum.class.cast(value).name().isEmpty() - && !Enum.class.cast(value).name().equalsIgnoreCase("DEFAULT")) { - return false; - } else if (String.class.isAssignableFrom(value.getClass()) && !value.toString().isEmpty()) { - return false; - } else if (value instanceof Annotation) { - if (!isAnnotationNull((Annotation) value)) { - return false; - } - } + // NB. annotation attribute values cannot be null + if (value.getClass().isArray() && Array.getLength(value) > 0) { + return false; + } else if (value instanceof Boolean && ((Boolean) value).booleanValue()) { + return false; + } else if (value instanceof Class && value != Void.class) { + return false; + } else if (value instanceof Enum && !((Enum) value).name().equalsIgnoreCase("DEFAULT")) { + return false; + } else if (value instanceof String && !value.toString().isEmpty()) { + return false; + } else if (value instanceof Annotation && !isAnnotationNull((Annotation) value)) { + return false; } + // else it must be another primitive wrapper but we have no rules on them } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { LOGGER.log(WARNING, "Unable to access annotation element.", ex); } @@ -456,7 +450,7 @@ public static void applyReference(org.eclipse.microprofile.openapi.models.Refere if (currentValue != null && !field.getName().equals("ref")) { // If the field is a collection, clear it if (Collection.class.isAssignableFrom(field.getType())) { - Collection.class.cast(field.get(referee)).clear(); + ((Collection) field.get(referee)).clear(); continue; } // If the field is an array, clear it @@ -499,19 +493,22 @@ public static void merge(T from, T to, boolean override) { Object currentValue = f.get(to); if (newValue != null) { if (newValue instanceof Map) { - for (Entry entry : (Set>) Map.class.cast(newValue) - .entrySet()) { - if (!Map.class.cast(currentValue).containsKey(entry.getKey())) { - Map.class.cast(currentValue).put(entry.getKey(), entry.getValue()); + Map newMap = (Map) newValue; + Map currentMap = (Map) currentValue; + for (Entry entry : newMap.entrySet()) { + if (!currentMap.containsKey(entry.getKey())) { + currentMap.put(entry.getKey(), entry.getValue()); } else { - merge(entry.getValue(), Map.class.cast(currentValue).get(entry.getKey()), override); + merge(entry.getValue(), currentMap.get(entry.getKey()), override); } } } else if (newValue instanceof Collection) { - for (Object o : Collection.class.cast(newValue)) { - if (!Collection.class.cast(currentValue).contains(o)) { - Collection.class.cast(currentValue).add(o); + Collection newCollection = (Collection) newValue; + Collection currentCollection = (Collection) currentValue; + for (Object o : newCollection) { + if (!currentCollection.contains(o)) { + currentCollection.add(o); } } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java index fa8884abf5a..b000f313715 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java @@ -409,7 +409,7 @@ public void visitFormParam(FormParam param, AnnotatedElement element, ApiContext SchemaType formSchemaType = null; if (element instanceof java.lang.reflect.Parameter) { - java.lang.reflect.Parameter[] parameters = java.lang.reflect.Parameter.class.cast(element) + java.lang.reflect.Parameter[] parameters = ((java.lang.reflect.Parameter) element) .getDeclaringExecutable().getParameters(); for (java.lang.reflect.Parameter methodParam : parameters) { if (methodParam.isAnnotationPresent(FormParam.class)) { @@ -505,10 +505,10 @@ private static SchemaImpl getArraySchema(AnnotatedElement element) { ParameterizedType parameterizedType; if (element instanceof java.lang.reflect.Parameter) { - java.lang.reflect.Parameter parameter = java.lang.reflect.Parameter.class.cast(element); + java.lang.reflect.Parameter parameter = (java.lang.reflect.Parameter) element; parameterizedType = (ParameterizedType) parameter.getParameterizedType(); } else { - Field field = Field.class.cast(element); + Field field = (Field) element; parameterizedType = (ParameterizedType) field.getAnnotatedType().getType(); } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtilsTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtilsTest.java index 95b41c38e1a..27cf23b264a 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtilsTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/impl/model/util/ModelUtilsTest.java @@ -39,8 +39,19 @@ */ package fish.payara.microprofile.openapi.impl.model.util; +import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.isAnnotationNull; import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.mergeProperty; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import org.junit.Test; @@ -65,4 +76,102 @@ public void mergePropertyTest() { assertEquals(NULL, mergeProperty(NULL, NULL, false)); } + enum TestEnum { + + DEFAULT, + OTHER + } + + @Target(ElementType.ANNOTATION_TYPE) + @Retention(RetentionPolicy.RUNTIME) + @interface NestedAnnotation { + String value() default ""; + } + + @Target(ElementType.FIELD) + @Retention(RetentionPolicy.RUNTIME) + @interface TestAnnotation { + String[] arrayAttribute() default {}; + boolean booleanAttribute() default false; + Class classAttribute() default Void.class; + TestEnum enumAttribute() default TestEnum.DEFAULT; + String stringAttribute() default ""; + NestedAnnotation annotationAttribute() default @NestedAnnotation(); + } + + @Target(ElementType.FIELD) + @Retention(RetentionPolicy.RUNTIME) + @interface MarkerAnnotation { + // has no attributes + } + + @TestAnnotation + private Object nullAnnotation; + @TestAnnotation(arrayAttribute = { "a" }) + private Object annotationWithArray; + @TestAnnotation(booleanAttribute = true) + private Object annotationWithBoolean; + @TestAnnotation(classAttribute = String.class) + private Object annotationWithClass; + @TestAnnotation(enumAttribute = TestEnum.OTHER) + private Object annoationWithEnum; + @TestAnnotation(annotationAttribute = @NestedAnnotation("value")) + private Object annoationWithAnnoation; + @MarkerAnnotation + private Object markerAnnoation; + + @Test + public void nullAnnoationIsNull() { + assertTrue(isAnnotationNull(null)); + } + + @Test + public void emptyAnnotationIsNull() { + assertTrue(isAnnotationNull(getFieldAnnotation("nullAnnotation"))); + } + + @Test + public void markerAnnoationIsNull() { + assertTrue(isAnnotationNull(getFieldAnnotation("markerAnnoation", MarkerAnnotation.class))); + } + + @Test + public void annotationWithNonEmptyArrayIsNotNull() { + assertFalse(isAnnotationNull(getFieldAnnotation("annotationWithArray"))); + } + + @Test + public void annotationWithNonFalseBooleanIsNotNull() { + assertFalse(isAnnotationNull(getFieldAnnotation("annotationWithBoolean"))); + } + + @Test + public void annotationWithNonVoidClassIsNotNull() { + assertFalse(isAnnotationNull(getFieldAnnotation("annotationWithClass"))); + } + + @Test + public void annotationWithNonDefaultEnumIsNotNull() { + assertFalse(isAnnotationNull(getFieldAnnotation("annoationWithEnum"))); + } + + @Test + public void annotationWithNonNullAnnoationIsNotNull() { + assertFalse(isAnnotationNull(getFieldAnnotation("annoationWithAnnoation"))); + } + + private TestAnnotation getFieldAnnotation(String fieldName) { + return getFieldAnnotation(fieldName, TestAnnotation.class); + } + + private T getFieldAnnotation(String fieldName, Class annoationType) { + try { + T annotation = getClass().getDeclaredField(fieldName).getAnnotation(annoationType); + assertNotNull(annotation); + return annotation; + } catch (NoSuchFieldException | SecurityException e) { + fail("Field expected: "+fieldName); + return null; + } + } } \ No newline at end of file From 2d2c2c88a2d95215767c6c4eb5718e93538e4b70 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Tue, 2 Apr 2019 19:32:16 +0200 Subject: [PATCH 103/108] PAYARA-3466 fixed toString for collection fields, moved walking part of processor to walker --- .../openapi/api/visitor/ApiContext.java | 6 + .../openapi/impl/model/ExtensibleImpl.java | 12 +- .../impl/processor/ApplicationProcessor.java | 132 +++--------------- .../openapi/impl/visitor/OpenApiContext.java | 14 +- .../openapi/impl/visitor/OpenApiWalker.java | 99 ++++++++++++- .../test/app/application/CallbacksTest.java | 1 - 6 files changed, 138 insertions(+), 126 deletions(-) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiContext.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiContext.java index 082f985c498..3e09d780573 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiContext.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/api/visitor/ApiContext.java @@ -64,4 +64,10 @@ public interface ApiContext { * The created operation currently being worked on. */ Operation getWorkingOperation(); + + /** + * @param type any class, not null + * @return true, if the give type is a known type in this context, else false + */ + boolean isApplicationType(Class type); } \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java index afb4c7ec765..59a3b589fe0 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/model/ExtensibleImpl.java @@ -173,7 +173,10 @@ void toString(StringBuilder str, String indent) { private static void toString(StringBuilder str, String indent, Object key, Object value) { if (isNonEmpty(value)) { - str.append("\n").append(indent).append('"').append(key).append('"').append(": "); + str.append("\n").append(indent); + if (key != null) { + str.append('"').append(key).append('"').append(": "); + } if (value instanceof ExtensibleImpl) { ((ExtensibleImpl)value).toString(str, indent + "\t"); } else if (value instanceof Map) { @@ -182,6 +185,13 @@ private static void toString(StringBuilder str, String indent, Object key, Objec toString(str, indent + '\t', entry.getKey(), entry.getValue()); } str.append('\n').append(indent).append('}'); + } else if (value instanceof Collection) { + str.append('['); + for (Object element : (Collection)value) { + toString(str, indent+ '\t', null, element); + str.append(','); + } + str.append('\n').append(indent).append(']'); } else if (value instanceof String) { str.append('"').append(value).append('"'); } else { diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java index b000f313715..52e4c4b7375 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/processor/ApplicationProcessor.java @@ -47,10 +47,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -58,7 +55,6 @@ import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.ws.rs.ApplicationPath; import javax.ws.rs.Consumes; import javax.ws.rs.CookieParam; import javax.ws.rs.DELETE; @@ -73,7 +69,6 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Application; import org.eclipse.microprofile.openapi.annotations.ExternalDocumentation; import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition; @@ -128,7 +123,6 @@ import fish.payara.microprofile.openapi.impl.model.tags.TagImpl; import fish.payara.microprofile.openapi.impl.model.util.AnnotationInfo; import fish.payara.microprofile.openapi.impl.model.util.ModelUtils; -import fish.payara.microprofile.openapi.impl.visitor.OpenApiContext; import fish.payara.microprofile.openapi.impl.visitor.OpenApiWalker; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; @@ -148,41 +142,19 @@ public class ApplicationProcessor implements OASProcessor, ApiVisitor { * A list of all classes in the given application. */ private final Set> classes; - + /** * @param appClassLoader the class loader for the application. */ public ApplicationProcessor(Set> appClasses) { this.classes = appClasses; this.classes.removeIf(cls -> cls.isInterface() || Modifier.isAbstract(cls.getModifiers())); - addInnerClasses(); } - private void addInnerClasses() { - List> topLevelClasses = new ArrayList<>(classes); - for (Class topLevelClass : topLevelClasses) { - addInnerClasses(topLevelClass); - } - } - - private void addInnerClasses(Class topLevelClass) { - if (topLevelClass != null) { - classes.addAll(Arrays.asList(topLevelClass.getDeclaredClasses())); - if (topLevelClass.getSuperclass() != Object.class) { - addInnerClasses(topLevelClass.getSuperclass()); - } - } - } - @Override public OpenAPI process(OpenAPI api, OpenApiConfiguration config) { - ApiWalker apiWalker = null; - if (config == null) { - apiWalker = new OpenApiWalker(api, classes, generateResourceMapping(classes)); - } else { - apiWalker = new OpenApiWalker(api, config.getValidClasses(classes), generateResourceMapping(classes)); - } if (config == null || !config.getScanDisable()) { + ApiWalker apiWalker = new OpenApiWalker(api, config == null ? classes : config.getValidClasses(classes)); apiWalker.accept(this); } return api; @@ -386,21 +358,12 @@ public void visitConsumes(Consumes consumes, AnnotatedElement element, ApiContex @Override public void visitQueryParam(QueryParam param, AnnotatedElement element, ApiContext context) { - org.eclipse.microprofile.openapi.models.parameters.Parameter newParameter = new ParameterImpl(); - newParameter.setName(param.value()); - newParameter.setIn(In.QUERY); - newParameter.setStyle(Style.SIMPLE); - addParameter(element, context, newParameter); + addParameter(element, context, param.value(), In.QUERY, null); } @Override public void visitPathParam(PathParam param, AnnotatedElement element, ApiContext context) { - org.eclipse.microprofile.openapi.models.parameters.Parameter newParameter = new ParameterImpl(); - newParameter.setName(param.value()); - newParameter.setRequired(true); - newParameter.setIn(In.PATH); - newParameter.setStyle(Style.SIMPLE); - addParameter(element, context, newParameter); + addParameter(element, context, param.value(), In.PATH, true); } @Override @@ -436,24 +399,20 @@ public void visitFormParam(FormParam param, AnnotatedElement element, ApiContext @Override public void visitHeaderParam(HeaderParam param, AnnotatedElement element, ApiContext context) { - org.eclipse.microprofile.openapi.models.parameters.Parameter newParameter = new ParameterImpl(); - newParameter.setName(param.value()); - newParameter.setIn(In.HEADER); - newParameter.setStyle(Style.SIMPLE); - addParameter(element, context, newParameter); + addParameter(element, context, param.value(), In.HEADER, null); } @Override public void visitCookieParam(CookieParam param, AnnotatedElement element, ApiContext context) { - org.eclipse.microprofile.openapi.models.parameters.Parameter newParameter = new ParameterImpl(); - newParameter.setName(param.value()); - newParameter.setIn(In.COOKIE); - newParameter.setStyle(Style.SIMPLE); - addParameter(element, context, newParameter); + addParameter(element, context, param.value(), In.COOKIE, null); } - private void addParameter(AnnotatedElement element, ApiContext context, - org.eclipse.microprofile.openapi.models.parameters.Parameter newParameter) { + private static void addParameter(AnnotatedElement element, ApiContext context, String name, In in, Boolean required) { + org.eclipse.microprofile.openapi.models.parameters.Parameter newParameter = new ParameterImpl(); + newParameter.setName(name); + newParameter.setIn(in); + newParameter.setStyle(Style.SIMPLE); + newParameter.setRequired(required); SchemaImpl schema = new SchemaImpl(); String defaultValue = getDefaultValueIfPresent(element); @@ -479,24 +438,9 @@ private void addParameter(AnnotatedElement element, ApiContext context, if (context.getWorkingOperation() != null) { context.getWorkingOperation().addParameter(newParameter); } else { - if (element instanceof Field) { - Field field = (Field) element; - ApiContext apiContext; - OpenAPI api = context.getApi(); - for (Method method : field.getDeclaringClass().getDeclaredMethods()) { - apiContext = new OpenApiContext(api, null, ModelUtils.getOperation(method, - api, generateResourceMapping(classes))); - if (apiContext.getWorkingOperation() != null) { - apiContext.getWorkingOperation().addParameter(newParameter); - } else { - LOGGER.log(SEVERE, "Method \"" + method.getName() + "\" has an unsupported annotation."); - } - } - } else { - LOGGER.log(SEVERE, "Couldn't add " + newParameter.getIn() + " parameter, \"" + newParameter.getName() - + "\" to the OpenAPI Document. This is usually caused by declaring parameter under a method with " - + "an unsupported annotation."); - } + LOGGER.log(SEVERE, "Couldn't add " + newParameter.getIn() + " parameter, \"" + newParameter.getName() + + "\" to the OpenAPI Document. This is usually caused by declaring parameter under a method with " + + "an unsupported annotation."); } } @@ -598,7 +542,7 @@ private void visitSchemaClass(Schema schema, Class clazz, ApiContext context) } } - private void visitSchemaField(Schema schema, Field field, ApiContext context) { + private static void visitSchemaField(Schema schema, Field field, ApiContext context) { // Get the schema object name String schemaName = schema.name(); if (schemaName == null || schemaName.isEmpty()) { @@ -625,7 +569,7 @@ private void visitSchemaField(Schema schema, Field field, ApiContext context) { SchemaImpl.merge(schema, property, true, context.getApi().getComponents().getSchemas()); } - private void visitSchemaParameter(Schema schema, java.lang.reflect.Parameter parameter, ApiContext context) { + private static void visitSchemaParameter(Schema schema, java.lang.reflect.Parameter parameter, ApiContext context) { // If this is being parsed at the start, ignore it as the path doesn't exist if (context.getWorkingOperation() == null) { return; @@ -925,46 +869,6 @@ public void visitSecurityRequirements(SecurityRequirements securityRequirements, // PRIVATE METHODS - /** - * Generates a map listing the location each resource class is mapped to. - */ - private static Map>> generateResourceMapping(Set> classList) { - Map>> resourceMapping = new HashMap<>(); - for (Class clazz : classList) { - if (clazz.isAnnotationPresent(ApplicationPath.class) && Application.class.isAssignableFrom(clazz)) { - // Produce the mapping - String key = clazz.getDeclaredAnnotation(ApplicationPath.class).value(); - Set> resourceClasses = new HashSet<>(); - resourceMapping.put(key, resourceClasses); - - try { - Application app = (Application) clazz.newInstance(); - // Add all classes contained in the application - resourceClasses.addAll(app.getClasses()); - // Remove all Jersey providers - resourceClasses.removeIf(resource -> resource.getPackage().getName().contains("org.glassfish.jersey")); - } catch (InstantiationException | IllegalAccessException ex) { - LOGGER.log(WARNING, "Unable to initialise application class.", ex); - } - } - } - - // If there is one application and it's empty, add all classes - if (resourceMapping.keySet().size() == 1) { - Set> classes = resourceMapping.values().iterator().next(); - if (classes.isEmpty()) { - classes.addAll(classList); - } - } - - // If there is no application, add all classes to the context root. - if (resourceMapping.isEmpty()) { - resourceMapping.put("/", classList); - } - - return resourceMapping; - } - private org.eclipse.microprofile.openapi.models.parameters.RequestBody insertDefaultRequestBody(ApiContext context, org.eclipse.microprofile.openapi.models.Operation operation, Method method) { org.eclipse.microprofile.openapi.models.parameters.RequestBody requestBody = new RequestBodyImpl(); @@ -1098,7 +1002,7 @@ private boolean insertObjectReference(ApiContext context, Reference referee, } // Check the class exists in the application - if (!classes.contains(referenceClass)) { + if (!context.isApplicationType(referenceClass)) { return false; } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiContext.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiContext.java index 0760e46265e..932b6535697 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiContext.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiContext.java @@ -39,6 +39,8 @@ */ package fish.payara.microprofile.openapi.impl.visitor; +import java.util.Set; + import org.eclipse.microprofile.openapi.models.OpenAPI; import org.eclipse.microprofile.openapi.models.Operation; @@ -46,18 +48,20 @@ public class OpenApiContext implements ApiContext { + private final Set> applicationClasses; private final OpenAPI api; private final String path; private final Operation operation; - public OpenApiContext(OpenAPI api, String path, Operation operation) { + public OpenApiContext(Set> applicationClasses, OpenAPI api, String path, Operation operation) { + this.applicationClasses = applicationClasses; this.api = api; this.path = path; this.operation = operation; } - public OpenApiContext(OpenAPI api, String path) { - this(api, path, null); + public OpenApiContext(Set> applicationClasses, OpenAPI api, String path) { + this(applicationClasses, api, path, null); } @Override @@ -75,4 +79,8 @@ public Operation getWorkingOperation() { return operation; } + @Override + public boolean isApplicationType(Class type) { + return applicationClasses.contains(type); + } } \ No newline at end of file diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java index 0addc8f87df..2bf49f5bd88 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/main/java/fish/payara/microprofile/openapi/impl/visitor/OpenApiWalker.java @@ -41,14 +41,21 @@ import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.getOperation; import static fish.payara.microprofile.openapi.impl.model.util.ModelUtils.getResourcePath; +import static java.util.logging.Level.WARNING; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; +import java.util.logging.Logger; import javax.ws.rs.ApplicationPath; import javax.ws.rs.Consumes; @@ -66,6 +73,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Application; import org.eclipse.microprofile.openapi.annotations.ExternalDocumentation; import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition; @@ -101,13 +109,14 @@ */ public class OpenApiWalker implements ApiWalker { + private static final Logger LOGGER = Logger.getLogger(OpenApiWalker.class.getName()); + private final OpenAPI api; private final Set> classes; private final Map>> resourceMapping; - public OpenApiWalker(OpenAPI api, Set> allowedClasses, Map>> resourceMapping) { + public OpenApiWalker(OpenAPI api, Set> allowedClasses) { this.api = api; - this.resourceMapping = resourceMapping; this.classes = new TreeSet<>((class1, class2) -> { if (class1.equals(class2)) { return 0; @@ -128,6 +137,24 @@ public OpenApiWalker(OpenAPI api, Set> allowedClasses, Map> topLevelClasses = new ArrayList<>(classes); + for (Class topLevelClass : topLevelClasses) { + addInnerClasses(topLevelClass); + } + } + + private void addInnerClasses(Class topLevelClass) { + if (topLevelClass != null) { + classes.addAll(Arrays.asList(topLevelClass.getDeclaredClasses())); + if (topLevelClass.getSuperclass() != Object.class) { + addInnerClasses(topLevelClass.getSuperclass()); + } + } } @Override @@ -195,16 +222,34 @@ private final void process Class... alternatives) { AnnotationInfo annotations = AnnotationInfo.valueOf(annotatedClass); processAnnotation(annotatedClass, annotationClass, annotationFunction, annotations, - new OpenApiContext(api, getResourcePath(annotatedClass, resourceMapping)), alternatives); + new OpenApiContext(classes, api, getResourcePath(annotatedClass, resourceMapping)), alternatives); for (Field field : annotatedClass.getDeclaredFields()) { - processAnnotation(field, annotationClass, annotationFunction, annotations, - new OpenApiContext(api, null), alternatives); + if (annotations.isAnnotationPresent(annotationClass, field)) { + if ( annotationClass == HeaderParam.class + || annotationClass == CookieParam.class + || annotationClass == PathParam.class + || annotationClass == QueryParam.class) { + // NB. if fields are annotated as Param all methods have it + for (Method method : annotatedClass.getDeclaredMethods()) { + OpenApiContext context = new OpenApiContext(classes, api, + getResourcePath(method, resourceMapping), + getOperation(method, api, resourceMapping)); + if (context.getWorkingOperation() != null) { + processAnnotation(field, annotationClass, annotationFunction, annotations, context, + alternatives); + } + } + } else { + processAnnotation(field, annotationClass, annotationFunction, annotations, + new OpenApiContext(classes, api, null), alternatives); + } + } } for (final Method method : annotatedClass.getDeclaredMethods()) { - OpenApiContext context = new OpenApiContext(api, - getResourcePath(method, resourceMapping), + OpenApiContext context = new OpenApiContext(classes, api, + getResourcePath(method, resourceMapping), getOperation(method, api, resourceMapping)); processAnnotation(method, annotationClass, annotationFunction, annotations, context, alternatives); @@ -231,4 +276,44 @@ private static void processAn } } } + + /** + * Generates a map listing the location each resource class is mapped to. + */ + private static Map>> generateResourceMapping(Set> classList) { + Map>> resourceMapping = new HashMap<>(); + for (Class clazz : classList) { + if (clazz.isAnnotationPresent(ApplicationPath.class) && Application.class.isAssignableFrom(clazz)) { + // Produce the mapping + String key = clazz.getDeclaredAnnotation(ApplicationPath.class).value(); + Set> resourceClasses = new HashSet<>(); + resourceMapping.put(key, resourceClasses); + + try { + Application app = (Application) clazz.newInstance(); + // Add all classes contained in the application + resourceClasses.addAll(app.getClasses()); + // Remove all Jersey providers + resourceClasses.removeIf(resource -> resource.getPackage().getName().contains("org.glassfish.jersey")); + } catch (InstantiationException | IllegalAccessException ex) { + LOGGER.log(WARNING, "Unable to initialise application class.", ex); + } + } + } + + // If there is one application and it's empty, add all classes + if (resourceMapping.keySet().size() == 1) { + Set> classes = resourceMapping.values().iterator().next(); + if (classes.isEmpty()) { + classes.addAll(classList); + } + } + + // If there is no application, add all classes to the context root. + if (resourceMapping.isEmpty()) { + resourceMapping.put("/", classList); + } + + return resourceMapping; + } } diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java index 3cc2a4af40b..ec919f23fb1 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/CallbacksTest.java @@ -62,7 +62,6 @@ import com.fasterxml.jackson.databind.JsonNode; import fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest; -import fish.payara.microprofile.openapi.test.util.JsonUtils; @OpenAPIDefinition( info = @Info(title = "title", version = "version"), From 4f1b34f51320fee955b29858e09681ebc3c9ffb4 Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Wed, 3 Apr 2019 10:38:49 +0200 Subject: [PATCH 104/108] PAYARA-3466 added tests for param annoations on fields --- .../test/app/application/FieldParamTest.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/FieldParamTest.java diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/FieldParamTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/FieldParamTest.java new file mode 100644 index 00000000000..186d4334c2e --- /dev/null +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/FieldParamTest.java @@ -0,0 +1,107 @@ +package fish.payara.microprofile.openapi.test.app.application; + +import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import javax.ws.rs.CookieParam; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; + +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +import fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest; + +/** + * TCK lacks tests for parameter annotations being used on fields which should add such parameters to all methods of the + * bean. + */ +@Path("/field-params") +public class FieldParamTest extends OpenApiApplicationTest { + + @PathParam("path") + private String pathParam; + + @CookieParam("cookie") + private String cookieParam; + + @HeaderParam("header") + private String headerParam; + + @QueryParam("query") + private String queryParam; + + @GET + public String getMethod() { + return ""; + } + + @PUT + public void putMethod(@SuppressWarnings("unused") @PathParam("extra") String extra) { + // just exist to see the document for them + } + + @Test + public void pathParamIsAddedToApiMethods() { + assertHasParameter("path", true); + } + + @Test + public void cookieParamIsAddedToApiMethods() { + assertHasParameter("cookie", false); + } + + @Test + public void headerParamIsAddedToApiMethods() { + assertHasParameter("header", false); + } + + @Test + public void queryParamIsAddedToApiMethods() { + assertHasParameter("query", false); + } + + @Test + public void fieldParamsDoNotRemoveParameterParams() { + assertEquals(4, path(getOpenAPIJson(), "paths./test/field-params.get.parameters").size()); + assertEquals(5, path(getOpenAPIJson(), "paths./test/field-params.put.parameters").size()); + assertParameter("extra", true, "paths./test/field-params.put.parameters"); + + } + + private void assertHasParameter(String name, boolean required) { + assertParameter(name, required, "paths./test/field-params.get.parameters"); + assertParameter(name, required, "paths./test/field-params.put.parameters"); + } + + private void assertParameter(String name, boolean required, String objectPath) { + JsonNode parameter = parameterWithName(name, path(getOpenAPIJson(), objectPath)); + assertNotNull(parameter); + assertRequired(required, parameter); + } + + private static void assertRequired(boolean required, JsonNode parameter) { + JsonNode requiredField = parameter.get("required"); + if (required) { + assertTrue(requiredField.booleanValue()); + } else { + assertTrue(requiredField == null || requiredField.isNull()); + } + } + + private static JsonNode parameterWithName(String name, JsonNode parameters) { + for (JsonNode parameter : parameters) { + if (parameter.get("name").textValue().equals(name)) { + return parameter; + } + } + return null; + } +} From 778e78642ed084411a0650a39d7bb01bceb8bacf Mon Sep 17 00:00:00 2001 From: Jan Bernitt Date: Wed, 3 Apr 2019 10:50:33 +0200 Subject: [PATCH 105/108] PAYARA-3466 added missing copyright headers --- .../test/app/application/FieldParamTest.java | 39 +++++++++++++++++++ .../app/application/SchemaExampleTest.java | 39 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/FieldParamTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/FieldParamTest.java index 186d4334c2e..1a65b779f57 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/FieldParamTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/FieldParamTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.test.app.application; import static fish.payara.microprofile.openapi.test.util.JsonUtils.path; diff --git a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaExampleTest.java b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaExampleTest.java index 1f567c2504e..60f9582560f 100644 --- a/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaExampleTest.java +++ b/appserver/payara-appserver-modules/microprofile/openapi/src/test/java/fish/payara/microprofile/openapi/test/app/application/SchemaExampleTest.java @@ -1,3 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ package fish.payara.microprofile.openapi.test.app.application; import static org.junit.Assert.assertEquals; From fe42d613be426b2a968f9dcc800d9f6598e83d95 Mon Sep 17 00:00:00 2001 From: Patrik Dudits Date: Wed, 3 Apr 2019 19:44:11 +0200 Subject: [PATCH 106/108] PAYARA-3674: Preserve Thread Context Class Loader in Weld executor service --- .../weld/services/ExecutorServicesImpl.java | 170 ++++++++++++++++-- 1 file changed, 153 insertions(+), 17 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/ExecutorServicesImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/ExecutorServicesImpl.java index ab807b6602d..a32415902c0 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/ExecutorServicesImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/ExecutorServicesImpl.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) [2016-2018] Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) [2016-2019] Payara Foundation and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -45,8 +45,14 @@ import java.util.List; import java.util.ArrayList; import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + import org.jboss.weld.executor.AbstractExecutorServices; import org.jboss.weld.manager.api.ExecutorServices; @@ -56,21 +62,25 @@ * @author steve */ public class ExecutorServicesImpl extends AbstractExecutorServices implements ExecutorServices { - + + private final ExecutorService taskExecutor; + private final ContextualTimerExecutor timerExecutor; private PayaraExecutorService executor; public ExecutorServicesImpl(PayaraExecutorService service) { executor = service; + taskExecutor = new ContextualTaskExecutor(); + timerExecutor = new ContextualTimerExecutor(); } @Override public ExecutorService getTaskExecutor() { - return executor.getUnderlyingExecutorService(); + return taskExecutor; } @Override public ScheduledExecutorService getTimerExecutor() { - return executor.getUnderlyingScheduledExecutorService(); + return timerExecutor; } @Override @@ -88,22 +98,148 @@ public Collection> wrap(Collection> wrapped = new ArrayList<>(tasks.size()); for (Callable task : tasks) { - wrapped.add(new Callable() { - @Override - public Object call() throws Exception { - ClassLoader old = Utility.setContextClassLoader(TCCL); - try { - return task.call(); - } finally { - Utility.setContextClassLoader(old); - } - } - - }); + wrapped.add(inContextClassloader(TCCL, task)); } return wrapped; } - + private static Callable inContextClassloader(ClassLoader contextClassLoader, Callable task) { + return () -> { + ClassLoader old = Utility.setContextClassLoader(contextClassLoader); + try { + return task.call(); + } finally { + Utility.setContextClassLoader(old); + } + }; + } + + private static Runnable inContextClassloader(ClassLoader contextClassLoader, Runnable task) { + return () -> { + ClassLoader old = Utility.setContextClassLoader(contextClassLoader); + try { + task.run(); + } finally { + Utility.setContextClassLoader(old); + } + }; + } + + private static Callable inCurrentContextClassloader(Callable task) { + return inContextClassloader(Thread.currentThread().getContextClassLoader(), task); + } + + private static Runnable inCurrentContextClassloader(Runnable task) { + return inContextClassloader(Thread.currentThread().getContextClassLoader(), task); + } + + class ContextualTaskExecutor implements ExecutorService { + private ExecutorService delegate; + + ContextualTaskExecutor() { + this.delegate = executor.getUnderlyingExecutorService(); + } + + @Override + public void shutdown() { + throw new IllegalStateException("Downstream service cannot request shutdown"); + } + + @Override + public List shutdownNow() { + throw new IllegalStateException("Downstream service cannot request shutdown"); + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + return delegate().awaitTermination(timeout, unit); + } + + @Override + public boolean isShutdown() { + return delegate().isShutdown(); + } + + @Override + public boolean isTerminated() { + return delegate().isTerminated(); + } + + @Override + public Future submit(Callable task) { + return delegate().submit(inCurrentContextClassloader(task)); + } + + @Override + public Future submit(Runnable task, T result) { + return delegate().submit(inCurrentContextClassloader(task), result); + } + + @Override + public Future submit(Runnable task) { + return delegate().submit(inCurrentContextClassloader(task)); + } + + @Override + public List> invokeAll(Collection> tasks) throws InterruptedException { + return delegate().invokeAll(wrap(tasks)); + } + + @Override + public List> invokeAll(Collection> tasks, long timeout, TimeUnit unit) throws InterruptedException { + return delegate().invokeAll(wrap(tasks), timeout, unit); + } + + @Override + public T invokeAny(Collection> tasks) throws InterruptedException, ExecutionException { + return delegate().invokeAny(wrap(tasks)); + } + + @Override + public T invokeAny(Collection> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return delegate().invokeAny(wrap(tasks), timeout, unit); + } + + @Override + public void execute(Runnable command) { + delegate().execute(inCurrentContextClassloader(command)); + } + + protected ExecutorService delegate() { + return delegate; + } + } + + class ContextualTimerExecutor extends ContextualTaskExecutor implements ScheduledExecutorService { + private final ScheduledExecutorService delegate; + + ContextualTimerExecutor() { + this.delegate = executor.getUnderlyingScheduledExecutorService(); + } + + protected ScheduledExecutorService delegate() { + return this.delegate; + } + + @Override + public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + return delegate().schedule(inCurrentContextClassloader(command), delay, unit); + } + + @Override + public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { + return delegate().schedule(inCurrentContextClassloader(callable), delay, unit); + } + + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { + return delegate().scheduleAtFixedRate(inCurrentContextClassloader(command), initialDelay, period, unit); + } + + @Override + public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { + return delegate().scheduleWithFixedDelay(inCurrentContextClassloader(command), initialDelay, delay, unit); + } + } } From 0b881559b7c623a0218117fdad4a7088540aab64 Mon Sep 17 00:00:00 2001 From: Sven Diedrichsen Date: Wed, 3 Apr 2019 22:32:31 +0200 Subject: [PATCH 107/108] Requested changes from code review. --- .../appclient/client/jws/boot/JWSACCMain.java | 4 ++-- .../enterprise/naming/util/NamingUtilsImpl.java | 14 ++++++-------- .../fish/payara/ejb/invoke/InvokeEJBServlet.java | 2 +- .../openid/OpenIdAuthenticationMechanism.java | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/jws/boot/JWSACCMain.java b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/jws/boot/JWSACCMain.java index 7d62f3d17c2..a6e0195ce04 100644 --- a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/jws/boot/JWSACCMain.java +++ b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/jws/boot/JWSACCMain.java @@ -44,7 +44,7 @@ import org.glassfish.appclient.client.acc.JWSACCClassLoader; import org.glassfish.appclient.common.Util; -import javax.swing.*; +import javax.swing.SwingUtilities; import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -365,7 +365,7 @@ public static void refreshPolicy(File policyFile) { /** *Writes the provided text to a temporary file marked for deletion on exit. - *@param the content to be written + *@param content the content to be written *@param prefix for the temp file, conforming to the File.createTempFile requirements *@param suffix for the temp file *@return File object for the newly-created temp file diff --git a/appserver/common/glassfish-naming/src/main/java/com/sun/enterprise/naming/util/NamingUtilsImpl.java b/appserver/common/glassfish-naming/src/main/java/com/sun/enterprise/naming/util/NamingUtilsImpl.java index 0dcc7e2e98e..ea81e40324e 100644 --- a/appserver/common/glassfish-naming/src/main/java/com/sun/enterprise/naming/util/NamingUtilsImpl.java +++ b/appserver/common/glassfish-naming/src/main/java/com/sun/enterprise/naming/util/NamingUtilsImpl.java @@ -57,8 +57,6 @@ import static com.sun.enterprise.naming.util.LogFacade.logger; import static org.glassfish.common.util.ObjectInputOutputStreamFactoryFactory.getFactory; -; - /** * This is a utils class for refactoring the following method. */ @@ -129,18 +127,18 @@ public Object makeCopyOfObject(Object obj) { } private Object deserialize(byte[] data) throws IOException, java.security.PrivilegedActionException { - try(final ObjectInputStream ois = + try (final ObjectInputStream ois = getFactory().createObjectInputStream(new ByteArrayInputStream(data))){ return AccessController.doPrivileged((PrivilegedExceptionAction) () -> ois.readObject()); } } private byte[] serialize(Object obj) throws IOException { - try(ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = getFactory().createObjectOutputStream(bos)) { - oos.writeObject(obj); - oos.flush(); - return bos.toByteArray(); + try (final ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + try (final ObjectOutputStream oos = getFactory().createObjectOutputStream(bos)) { + oos.writeObject(obj); + } + return bos.toByteArray(); } } } diff --git a/appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java b/appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java index fd0ee0ccd0b..3611479f28f 100644 --- a/appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java +++ b/appserver/ejb/ejb-http-remoting/endpoint/src/main/java/fish/payara/ejb/invoke/InvokeEJBServlet.java @@ -177,7 +177,7 @@ private Class toClass(JsonValue classNameValue) { } private Object toObject(JsonValue objectValue, Class type) { - try(Jsonb jsonb = JsonbBuilder.create()) { + try (Jsonb jsonb = JsonbBuilder.create()) { return jsonb.fromJson(objectValue.toString(), type); } catch (Exception e) { // cannot really happen. It is just from java.lang.AutoCloseable interface diff --git a/appserver/payara-appserver-modules/security-openid/src/main/java/fish/payara/security/openid/OpenIdAuthenticationMechanism.java b/appserver/payara-appserver-modules/security-openid/src/main/java/fish/payara/security/openid/OpenIdAuthenticationMechanism.java index 7b26296aad6..31ec9b570b4 100644 --- a/appserver/payara-appserver-modules/security-openid/src/main/java/fish/payara/security/openid/OpenIdAuthenticationMechanism.java +++ b/appserver/payara-appserver-modules/security-openid/src/main/java/fish/payara/security/openid/OpenIdAuthenticationMechanism.java @@ -244,7 +244,7 @@ private AuthenticationStatus validateAuthorizationCode(HttpMessageContext httpCo } private JsonObject readJsonObject(String tokensBody) { - try(JsonReader reader = Json.createReader(new StringReader(tokensBody))) { + try (JsonReader reader = Json.createReader(new StringReader(tokensBody))) { return reader.readObject(); } } From 9d15053a8f23202040f4e94935871ab60c4fba27 Mon Sep 17 00:00:00 2001 From: Steve Millidge Date: Sun, 7 Apr 2019 14:19:13 +0100 Subject: [PATCH 108/108] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 336f4669f41..230dfe8a94a 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -19,7 +19,8 @@