diff --git a/features/org.eclipse.emf.cdo-feature/feature.xml b/features/org.eclipse.emf.cdo-feature/feature.xml index 087157e438e..60ede9807d0 100644 --- a/features/org.eclipse.emf.cdo-feature/feature.xml +++ b/features/org.eclipse.emf.cdo-feature/feature.xml @@ -37,163 +37,94 @@ + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> diff --git a/features/org.eclipse.emf.cdo.doc-feature/feature.xml b/features/org.eclipse.emf.cdo.doc-feature/feature.xml index 6c0801f141a..591b6732d99 100644 --- a/features/org.eclipse.emf.cdo.doc-feature/feature.xml +++ b/features/org.eclipse.emf.cdo.doc-feature/feature.xml @@ -12,7 +12,7 @@ @@ -40,9 +40,6 @@ + version="0.0.0"/> diff --git a/features/org.eclipse.emf.cdo.doc-feature/pom.xml b/features/org.eclipse.emf.cdo.doc-feature/pom.xml index 76f72e82876..ad19243ce2e 100644 --- a/features/org.eclipse.emf.cdo.doc-feature/pom.xml +++ b/features/org.eclipse.emf.cdo.doc-feature/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo.features org.eclipse.emf.cdo.doc - 4.3.11-SNAPSHOT + 4.3.12-SNAPSHOT eclipse-feature diff --git a/features/org.eclipse.emf.cdo.server.db-feature/feature.xml b/features/org.eclipse.emf.cdo.server.db-feature/feature.xml index 87361c806d6..46a3a85d208 100644 --- a/features/org.eclipse.emf.cdo.server.db-feature/feature.xml +++ b/features/org.eclipse.emf.cdo.server.db-feature/feature.xml @@ -12,7 +12,7 @@ @@ -36,9 +36,6 @@ + version="0.0.0"/> diff --git a/features/org.eclipse.emf.cdo.server.db-feature/pom.xml b/features/org.eclipse.emf.cdo.server.db-feature/pom.xml index 9b4b71f7210..bbb14578251 100644 --- a/features/org.eclipse.emf.cdo.server.db-feature/pom.xml +++ b/features/org.eclipse.emf.cdo.server.db-feature/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo.features org.eclipse.emf.cdo.server.db - 4.13.1-SNAPSHOT + 4.13.2-SNAPSHOT eclipse-feature diff --git a/features/org.eclipse.net4j-feature/feature.xml b/features/org.eclipse.net4j-feature/feature.xml index 15406688f64..ef6fac59995 100644 --- a/features/org.eclipse.net4j-feature/feature.xml +++ b/features/org.eclipse.net4j-feature/feature.xml @@ -12,7 +12,7 @@ org.eclipse.emf.cdo.features org.eclipse.net4j - 4.25.0-SNAPSHOT + 4.26.0-SNAPSHOT eclipse-feature diff --git a/features/org.eclipse.net4j.sdk-feature/feature.xml b/features/org.eclipse.net4j.sdk-feature/feature.xml index d22eee7790b..157b5fa534f 100644 --- a/features/org.eclipse.net4j.sdk-feature/feature.xml +++ b/features/org.eclipse.net4j.sdk-feature/feature.xml @@ -12,7 +12,7 @@ + version="0.0.0"/> diff --git a/features/org.eclipse.net4j.sdk-feature/pom.xml b/features/org.eclipse.net4j.sdk-feature/pom.xml index 2f97167bea1..7c8dbef331a 100644 --- a/features/org.eclipse.net4j.sdk-feature/pom.xml +++ b/features/org.eclipse.net4j.sdk-feature/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo.features org.eclipse.net4j.sdk - 4.27.0-SNAPSHOT + 4.27.1-SNAPSHOT eclipse-feature diff --git a/features/org.eclipse.net4j.ui-feature/feature.xml b/features/org.eclipse.net4j.ui-feature/feature.xml index 28ced3f0cf4..735455804b6 100644 --- a/features/org.eclipse.net4j.ui-feature/feature.xml +++ b/features/org.eclipse.net4j.ui-feature/feature.xml @@ -12,7 +12,7 @@ + + + version="0.0.0"/> + version="0.0.0"/> diff --git a/features/org.eclipse.net4j.ui-feature/pom.xml b/features/org.eclipse.net4j.ui-feature/pom.xml index b6a391262da..aa3c707ab4c 100644 --- a/features/org.eclipse.net4j.ui-feature/pom.xml +++ b/features/org.eclipse.net4j.ui-feature/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo.features org.eclipse.net4j.ui - 4.8.2-SNAPSHOT + 4.9.0-SNAPSHOT eclipse-feature diff --git a/features/org.eclipse.net4j.ws-feature/feature.xml b/features/org.eclipse.net4j.ws-feature/feature.xml index bdbebda432b..83479771298 100644 --- a/features/org.eclipse.net4j.ws-feature/feature.xml +++ b/features/org.eclipse.net4j.ws-feature/feature.xml @@ -12,7 +12,7 @@ download-size="0" install-size="0" version="0.0.0" unpack="false"/> + + + + + + + + + diff --git a/features/org.eclipse.net4j.ws-feature/pom.xml b/features/org.eclipse.net4j.ws-feature/pom.xml index ef76a9331c7..4c9f9e077ae 100644 --- a/features/org.eclipse.net4j.ws-feature/pom.xml +++ b/features/org.eclipse.net4j.ws-feature/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo.features org.eclipse.net4j.ws - 1.2.5-SNAPSHOT + 1.3.0-SNAPSHOT eclipse-feature diff --git a/plugins/org.eclipse.emf.cdo.doc/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.doc/META-INF/MANIFEST.MF index 12c80b1a4a5..133bb3a5427 100644 --- a/plugins/org.eclipse.emf.cdo.doc/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.doc/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.emf.cdo.doc; singleton:=true -Bundle-Version: 4.2.11.qualifier +Bundle-Version: 4.2.12.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -12,6 +12,7 @@ Require-Bundle: org.eclipse.help;bundle-version="[3.3.0,4.0.0)";resolution:=opti org.eclipse.ui.intro.universal;bundle-version="[3.2.0,4.0.0)";resolution:=optional, org.eclipse.net4j.db.doc;bundle-version="[4.0.0,5.0.0)";resolution:=optional;visibility:=reexport, org.eclipse.net4j.doc;bundle-version="[4.0.0,5.0.0)";resolution:=optional;visibility:=reexport, + org.eclipse.net4j.ws;bundle-version="[1.3.0,2.0.0)";resolution:=optional;visibility:=reexport, org.eclipse.emf.cdo;bundle-version="[4.0.0,5.0.0)";resolution:=optional;visibility:=reexport, org.eclipse.emf.cdo.common;bundle-version="[4.0.0,5.0.0)";resolution:=optional;visibility:=reexport, org.eclipse.emf.cdo.edit;bundle-version="[4.0.0,5.0.0)";resolution:=optional;visibility:=reexport, @@ -23,15 +24,15 @@ Require-Bundle: org.eclipse.help;bundle-version="[3.3.0,4.0.0)";resolution:=opti org.eclipse.emf.cdo.server.ocl;bundle-version="[4.0.0,5.0.0)";resolution:=optional;visibility:=reexport, org.eclipse.emf.cdo.ui;bundle-version="[4.0.0,5.0.0)";resolution:=optional;visibility:=reexport, org.eclipse.emf.cdo.explorer;bundle-version="[4.0.0,5.0.0)";resolution:=optional -Export-Package: org.eclipse.emf.cdo.doc;version="4.2.11", - org.eclipse.emf.cdo.doc.online;version="4.2.11", - org.eclipse.emf.cdo.doc.operators;version="4.2.11", - org.eclipse.emf.cdo.doc.programmers;version="4.2.11", - org.eclipse.emf.cdo.doc.programmers.client;version="4.2.11", - org.eclipse.emf.cdo.doc.programmers.server;version="4.2.11", - org.eclipse.emf.cdo.doc.reference;version="4.2.11", - org.eclipse.emf.cdo.doc.reference.api;version="4.2.11", - org.eclipse.emf.cdo.doc.reference.product;version="4.2.11", - org.eclipse.emf.cdo.doc.reference.schema;version="4.2.11", - org.eclipse.emf.cdo.doc.users;version="4.2.11" +Export-Package: org.eclipse.emf.cdo.doc;version="4.2.12", + org.eclipse.emf.cdo.doc.online;version="4.2.12", + org.eclipse.emf.cdo.doc.operators;version="4.2.12", + org.eclipse.emf.cdo.doc.programmers;version="4.2.12", + org.eclipse.emf.cdo.doc.programmers.client;version="4.2.12", + org.eclipse.emf.cdo.doc.programmers.server;version="4.2.12", + org.eclipse.emf.cdo.doc.reference;version="4.2.12", + org.eclipse.emf.cdo.doc.reference.api;version="4.2.12", + org.eclipse.emf.cdo.doc.reference.product;version="4.2.12", + org.eclipse.emf.cdo.doc.reference.schema;version="4.2.12", + org.eclipse.emf.cdo.doc.users;version="4.2.12" Automatic-Module-Name: org.eclipse.emf.cdo.doc diff --git a/plugins/org.eclipse.emf.cdo.doc/pom.xml b/plugins/org.eclipse.emf.cdo.doc/pom.xml index a2ce080d77c..5327264da01 100644 --- a/plugins/org.eclipse.emf.cdo.doc/pom.xml +++ b/plugins/org.eclipse.emf.cdo.doc/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo org.eclipse.emf.cdo.doc - 4.2.11-SNAPSHOT + 4.2.12-SNAPSHOT eclipse-plugin diff --git a/plugins/org.eclipse.emf.cdo.ecore.retrofit/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.ecore.retrofit/META-INF/MANIFEST.MF index 385871fb1d5..2f8eae8e596 100644 --- a/plugins/org.eclipse.emf.cdo.ecore.retrofit/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.ecore.retrofit/META-INF/MANIFEST.MF @@ -7,5 +7,5 @@ Fragment-Host: org.eclipse.emf.ecore;bundle-version="[2.5.0,3.0.0)" Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-Vendor: %providerName Bundle-Localization: fragment -Export-Package: org.eclipse.emf.ecore.impl +Export-Package: org.eclipse.emf.ecore.impl;version="4.2.600" Automatic-Module-Name: org.eclipse.emf.cdo.ecore.retrofit diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.explorer.ui/META-INF/MANIFEST.MF index 530ebabd3e7..77ba34e3257 100644 --- a/plugins/org.eclipse.emf.cdo.explorer.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.explorer.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.emf.cdo.explorer.ui;singleton:=true -Bundle-Version: 4.7.12.qualifier +Bundle-Version: 4.7.13.qualifier Bundle-Activator: org.eclipse.emf.cdo.explorer.ui.bundle.OM$Activator Bundle-Vendor: %providerName Bundle-ClassPath: . @@ -25,17 +25,17 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.emf.cdo.ui.shared;bundle-version="[4.0.0,5.0.0)", org.eclipse.emf.cdo.ui.compare;bundle-version="[4.0.0,5.0.0)";resolution:=optional, org.eclipse.emf.cdo.ui.team;bundle-version="[4.0.0,5.0.0)";resolution:=optional -Export-Package: org.eclipse.emf.cdo.explorer.ui;version="4.7.12";x-internal:=true, - org.eclipse.emf.cdo.explorer.ui.actions;version="4.7.12";x-internal:=true, - org.eclipse.emf.cdo.explorer.ui.application;version="4.7.12";x-internal:=true, - org.eclipse.emf.cdo.explorer.ui.bundle;version="4.7.12";x-internal:=true, - org.eclipse.emf.cdo.explorer.ui.checkouts;version="4.7.12";x-internal:=true, - org.eclipse.emf.cdo.explorer.ui.checkouts.actions;version="4.7.12";x-internal:=true, - org.eclipse.emf.cdo.explorer.ui.checkouts.wizards;version="4.7.12";x-internal:=true, - org.eclipse.emf.cdo.explorer.ui.checkouts.workingsets;version="4.7.12";x-internal:=true, - org.eclipse.emf.cdo.explorer.ui.handlers;version="4.7.12";x-internal:=true, - org.eclipse.emf.cdo.explorer.ui.properties;version="4.7.12";x-internal:=true, - org.eclipse.emf.cdo.explorer.ui.repositories;version="4.7.12";x-internal:=true, - org.eclipse.emf.cdo.explorer.ui.repositories.wizards;version="4.7.12";x-internal:=true +Export-Package: org.eclipse.emf.cdo.explorer.ui;version="4.7.13";x-internal:=true, + org.eclipse.emf.cdo.explorer.ui.actions;version="4.7.13";x-internal:=true, + org.eclipse.emf.cdo.explorer.ui.application;version="4.7.13";x-internal:=true, + org.eclipse.emf.cdo.explorer.ui.bundle;version="4.7.13";x-internal:=true, + org.eclipse.emf.cdo.explorer.ui.checkouts;version="4.7.13";x-internal:=true, + org.eclipse.emf.cdo.explorer.ui.checkouts.actions;version="4.7.13";x-internal:=true, + org.eclipse.emf.cdo.explorer.ui.checkouts.wizards;version="4.7.13";x-internal:=true, + org.eclipse.emf.cdo.explorer.ui.checkouts.workingsets;version="4.7.13";x-internal:=true, + org.eclipse.emf.cdo.explorer.ui.handlers;version="4.7.13";x-internal:=true, + org.eclipse.emf.cdo.explorer.ui.properties;version="4.7.13";x-internal:=true, + org.eclipse.emf.cdo.explorer.ui.repositories;version="4.7.13";x-internal:=true, + org.eclipse.emf.cdo.explorer.ui.repositories.wizards;version="4.7.13";x-internal:=true Eclipse-BuddyPolicy: registered Automatic-Module-Name: org.eclipse.emf.cdo.explorer.ui diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/pom.xml b/plugins/org.eclipse.emf.cdo.explorer.ui/pom.xml index d2d280aeaa4..713d2fdbec4 100644 --- a/plugins/org.eclipse.emf.cdo.explorer.ui/pom.xml +++ b/plugins/org.eclipse.emf.cdo.explorer.ui/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo org.eclipse.emf.cdo.explorer.ui - 4.7.12-SNAPSHOT + 4.7.13-SNAPSHOT eclipse-plugin diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/actions/CheckoutCommitInfoActionDelegate.java b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/actions/CheckoutCommitInfoActionDelegate.java index 9e6ae30e0a8..31aa2768c51 100644 --- a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/actions/CheckoutCommitInfoActionDelegate.java +++ b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/actions/CheckoutCommitInfoActionDelegate.java @@ -24,6 +24,7 @@ import org.eclipse.net4j.util.ui.actions.LongRunningActionDelegate; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; @@ -40,55 +41,77 @@ public CheckoutCommitInfoActionDelegate() protected void doRun(IProgressMonitor progressMonitor) throws Exception { ISelection selection = getSelection(); - if (selection instanceof IStructuredSelection) + final CDOCommitInfo commitInfo = getCDOCommitInfo(selection); + final CDOSession session = CDOUtil.getSession(commitInfo); + if (session != null) { - IStructuredSelection ssel = (IStructuredSelection)selection; - if (ssel.size() == 1) + final CDORepository repository = (CDORepository)session.properties().get(CDORepositoryImpl.REPOSITORY_KEY); + if (repository != null) { - Object element = ssel.getFirstElement(); - if (element instanceof CDOCommitInfo) + CDORepositoryElement repositoryElement = new CDORepositoryElement() { - CDOCommitInfo commitInfo = (CDOCommitInfo)element; + @Override + public CDORepository getRepository() + { + return repository; + } - CDOSession session = CDOUtil.getSession(commitInfo); - if (session != null) + @Override + public int getBranchID() { - final CDORepository repository = (CDORepository)session.properties().get(CDORepositoryImpl.REPOSITORY_KEY); - if (repository != null) - { - CDORepositoryElement repositoryElement = new CDORepositoryElement() - { - @Override - public CDORepository getRepository() - { - return repository; - } + return commitInfo.getBranch().getID(); + } - @Override - public int getBranchID() - { - return commitInfo.getBranch().getID(); - } + @Override + public long getTimeStamp() + { + return commitInfo.getTimeStamp(); + } - @Override - public long getTimeStamp() - { - return commitInfo.getTimeStamp(); - } + @Override + public CDOID getObjectID() + { + return session.getRepositoryInfo().getRootResourceID(); + } + }; - @Override - public CDOID getObjectID() - { - return session.getRepositoryInfo().getRootResourceID(); - } - }; + checkout(repositoryElement); + } + } + } - checkout(repositoryElement); - } - } + private CDOCommitInfo getCDOCommitInfo(ISelection selection) + { + CDOCommitInfo commitInfo = null; + if (selection instanceof IStructuredSelection) + { + IStructuredSelection ssel = (IStructuredSelection)selection; + if (ssel.size() == 1) + { + Object element = ssel.getFirstElement(); + if (element instanceof CDOCommitInfo) + { + commitInfo = (CDOCommitInfo)element; } } } + return commitInfo; + } + + /** + * This method is overridden so that the action can be disabled if the branching is not supported. + */ + @Override + public void selectionChanged(IAction action, ISelection selection) + { + CDOCommitInfo commitInfo = getCDOCommitInfo(selection); + CDOSession session = CDOUtil.getSession(commitInfo); + if (session != null) + { + boolean supportingBranches = session.getRepositoryInfo().isSupportingBranches(); + action.setEnabled(supportingBranches); + } + super.selectionChanged(action, selection); } protected void checkout(CDORepositoryElement repositoryElement) diff --git a/plugins/org.eclipse.emf.cdo.net4j/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.net4j/META-INF/MANIFEST.MF index 8148532b2b5..e6e4060aaf9 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.net4j/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.emf.cdo.net4j; singleton:=true -Bundle-Version: 4.6.4.qualifier +Bundle-Version: 4.7.0.qualifier Bundle-ClassPath: . Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -10,11 +10,11 @@ Bundle-Activator: org.eclipse.emf.cdo.internal.net4j.bundle.OM$Activator Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Require-Bundle: org.eclipse.emf.cdo;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, org.eclipse.net4j;bundle-version="[4.0.0,5.0.0)";visibility:=reexport -Export-Package: org.eclipse.emf.cdo.internal.net4j;version="4.6.4";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.ui,org.eclipse.emf.cdo.examples", - org.eclipse.emf.cdo.internal.net4j.bundle;version="4.6.4";x-friends:="org.eclipse.emf.cdo.tests", - org.eclipse.emf.cdo.internal.net4j.messages;version="4.6.4";x-internal:=true, - org.eclipse.emf.cdo.internal.net4j.protocol;version="4.6.4";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.ui,org.eclipse.emf.cdo.examples", - org.eclipse.emf.cdo.internal.net4j.testrecorder;version="4.6.4";x-internal:=true, - org.eclipse.emf.cdo.net4j;version="4.6.4" +Export-Package: org.eclipse.emf.cdo.internal.net4j;version="4.7.0";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.ui,org.eclipse.emf.cdo.examples", + org.eclipse.emf.cdo.internal.net4j.bundle;version="4.7.0";x-friends:="org.eclipse.emf.cdo.tests", + org.eclipse.emf.cdo.internal.net4j.messages;version="4.7.0";x-internal:=true, + org.eclipse.emf.cdo.internal.net4j.protocol;version="4.7.0";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.ui,org.eclipse.emf.cdo.examples", + org.eclipse.emf.cdo.internal.net4j.testrecorder;version="4.7.0";x-internal:=true, + org.eclipse.emf.cdo.net4j;version="4.7.0" Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.emf.cdo.net4j diff --git a/plugins/org.eclipse.emf.cdo.net4j/plugin.xml b/plugins/org.eclipse.emf.cdo.net4j/plugin.xml index ae645f5c178..916a9becf6e 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/plugin.xml +++ b/plugins/org.eclipse.emf.cdo.net4j/plugin.xml @@ -45,6 +45,10 @@ + + @@ -64,6 +68,11 @@ class="org.eclipse.emf.cdo.net4j.CDONet4jViewProvider$WS" priority="500" regex="cdo\.net4j\.ws://.*"/> + + diff --git a/plugins/org.eclipse.emf.cdo.net4j/pom.xml b/plugins/org.eclipse.emf.cdo.net4j/pom.xml index fbea491edb8..45b834cd4ba 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/pom.xml +++ b/plugins/org.eclipse.emf.cdo.net4j/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo org.eclipse.emf.cdo.net4j - 4.6.4-SNAPSHOT + 4.7.0-SNAPSHOT eclipse-plugin diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/net4j/CDONet4jUtil.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/net4j/CDONet4jUtil.java index 2c5f0fe7654..8a8fdf4f3f1 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/net4j/CDONet4jUtil.java +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/net4j/CDONet4jUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2013, 2015, 2016, 2019, 2020, 2023 Eike Stepper (Loehne, Germany) and others. + * Copyright (c) 2009-2013, 2015, 2016, 2019, 2020, 2023, 2024 Eike Stepper (Loehne, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,6 +9,7 @@ * Eike Stepper - initial API and implementation * Simon McDuff - maintenance * Victor Roldan Betancort - maintenance + * Maxime Porhel (Obeo) - WSS Support */ package org.eclipse.emf.cdo.net4j; @@ -60,6 +61,11 @@ public final class CDONet4jUtil */ public static final String PROTOCOL_WS = "cdo.net4j.ws"; + /** + * @since 4.7 + */ + public static final String PROTOCOL_WSS = "cdo.net4j.wss"; + static { try @@ -84,6 +90,11 @@ public final class CDONet4jUtil map.put(PROTOCOL_WS, CDOResourceFactory.INSTANCE); } + if (!map.containsKey(PROTOCOL_WSS)) + { + map.put(PROTOCOL_WSS, CDOResourceFactory.INSTANCE); + } + if (!map.containsKey(PROTOCOL_JVM)) { map.put(PROTOCOL_JVM, CDOResourceFactory.INSTANCE); @@ -94,6 +105,7 @@ public final class CDONet4jUtil CDOViewProviderRegistry.INSTANCE.addViewProvider(new CDONet4jViewProvider.TCP(priority)); CDOViewProviderRegistry.INSTANCE.addViewProvider(new CDONet4jViewProvider.SSL(priority)); CDOViewProviderRegistry.INSTANCE.addViewProvider(new CDONet4jViewProvider.WS(priority)); + CDOViewProviderRegistry.INSTANCE.addViewProvider(new CDONet4jViewProvider.WSS(priority)); } } catch (RuntimeException ex) diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/net4j/CDONet4jViewProvider.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/net4j/CDONet4jViewProvider.java index c4d07e1c50a..549825017bb 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/net4j/CDONet4jViewProvider.java +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/net4j/CDONet4jViewProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2012, 2015, 2016, 2019, 2020 Eike Stepper (Loehne, Germany) and others. + * Copyright (c) 2010-2012, 2015, 2016, 2019, 2020, 2022 Eike Stepper (Loehne, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Maxime Porhel (Obeo) - WSS Support */ package org.eclipse.emf.cdo.net4j; @@ -164,7 +165,21 @@ public URI getResourceURI(String transport, String authority, String repositoryN CDOURIUtil.appendQueryParameter(query, CDOURIData.TRANSACTIONAL_PARAMETER, "true"); } - URI uri = URI.createHierarchicalURI("cdo.net4j." + transport, authority, null, query.toString(), null).appendSegment(repositoryName); + String[] servicePathSegments = null; + if (authority.contains(CDOURIUtil.SEGMENT_SEPARATOR)) + { + URI uri = URI.createURI(transport + "://" + authority); + authority = uri.authority(); + servicePathSegments = uri.segments(); + } + + URI uri = URI.createHierarchicalURI("cdo.net4j." + transport, authority, null, query.toString(), null); + + if (servicePathSegments != null && servicePathSegments.length > 0) + { + uri = uri.appendSegments(servicePathSegments); + } + uri = uri.appendSegment(repositoryName); return CDOURIUtil.appendResourcePath(uri, resourcePath); } @@ -337,6 +352,14 @@ public static class WS extends CDONet4jViewProvider { public static final String ACCEPTOR_NAME_PREFIX = "@"; + /** + * @since 4.7 + */ + protected WS(String transport, int priority) + { + super(transport, priority); + } + public WS(int priority) { super("ws", priority); @@ -412,4 +435,24 @@ protected int getAcceptorSegmentIndex(IPath path) return -1; } } + + /** + * An WSS-based {@link CDONet4jViewProvider view provider}. + * + * @author Maxime Porhel (Obeo) + * @since 4.7 + */ + public static class WSS extends WS + { + public WSS(int priority) + { + super("wss", priority); + } + + public WSS() + { + this(DEFAULT_PRIORITY); + } + + } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF index 1af24ae6f56..3c0ac01d456 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.server.db/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.emf.cdo.server.db;singleton:=true -Bundle-Version: 4.13.1.qualifier +Bundle-Version: 4.13.2.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -12,11 +12,11 @@ Bundle-ClassPath: . Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.net4j.db;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, org.eclipse.emf.cdo.server;bundle-version="[4.0.0,5.0.0)";visibility:=reexport -Export-Package: org.eclipse.emf.cdo.server.db;version="4.13.1", - org.eclipse.emf.cdo.server.db.mapping;version="4.13.1", - org.eclipse.emf.cdo.server.internal.db;version="4.13.1";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db,org.eclipse.emf.cdo.explorer.ui", - org.eclipse.emf.cdo.server.internal.db.bundle;version="4.13.1";x-internal:=true, - org.eclipse.emf.cdo.server.internal.db.mapping;version="4.13.1";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db", - org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;version="4.13.1";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db", - org.eclipse.emf.cdo.server.internal.db.messages;version="4.13.1";x-internal:=true +Export-Package: org.eclipse.emf.cdo.server.db;version="4.13.2", + org.eclipse.emf.cdo.server.db.mapping;version="4.13.2", + org.eclipse.emf.cdo.server.internal.db;version="4.13.2";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db,org.eclipse.emf.cdo.explorer.ui", + org.eclipse.emf.cdo.server.internal.db.bundle;version="4.13.2";x-internal:=true, + org.eclipse.emf.cdo.server.internal.db.mapping;version="4.13.2";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db", + org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;version="4.13.2";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db", + org.eclipse.emf.cdo.server.internal.db.messages;version="4.13.2";x-internal:=true Automatic-Module-Name: org.eclipse.emf.cdo.server.db diff --git a/plugins/org.eclipse.emf.cdo.server.db/pom.xml b/plugins/org.eclipse.emf.cdo.server.db/pom.xml index f9aedf6fea7..a339ef7d2a8 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/pom.xml +++ b/plugins/org.eclipse.emf.cdo.server.db/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo org.eclipse.emf.cdo.server.db - 4.13.1-SNAPSHOT + 4.13.2-SNAPSHOT eclipse-plugin diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java index dee99b43f05..7272a6bdcd6 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalMappingStrategy.java @@ -428,6 +428,16 @@ protected void doActivate() throws Exception protected void doDeactivate() throws Exception { LifecycleUtil.deactivate(objectTypeMapper); + + if (resourceFolderMapping != null) + { + // They will be deactivated in super.deactivateClassMappings(); + resourceFolderMapping = null; + modelResourceMapping = null; + textResourceMapping = null; + binaryResourceMapping = null; + } + super.doDeactivate(); } diff --git a/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF index b5e304a6938..ff5a6687755 100644 --- a/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF @@ -40,18 +40,23 @@ Require-Bundle: org.eclipse.net4j.tests;bundle-version="[4.0.0,5.0.0)";visibilit com.google.guava;bundle-version="[27.0.0,34.0.0)", com.google.guava.failureaccess;bundle-version="[1.0.0,2.0.0)", org.eclipse.emf.cdo.server.db;bundle-version="[4.0.0,5.0.0)", - org.eclipse.jetty.server;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.servlet;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.security;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.client;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.http;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.util;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.io;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.common;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.servlet;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.server;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.client;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.api;bundle-version="[10.0.0,11.0.0)" + org.eclipse.jetty.client;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.http;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.io;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.security;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.server;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.session;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.util;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.security;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.server;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.servlet;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.api;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.common;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.servlet;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.server;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.websocket.core.client;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.websocket.core.common;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.websocket.core.server;bundle-version="[12.0.0,13.0.0)" Import-Package: javax.servlet;version="[2.3.0,5.0.0)", javax.servlet.http;version="[2.3.0,5.0.0)" Export-Package: Testmodel562011;version="4.2.4", diff --git a/plugins/org.eclipse.emf.cdo.tests/launches/CDO AllTests (WSS).launch b/plugins/org.eclipse.emf.cdo.tests/launches/CDO AllTests (WSS).launch new file mode 100644 index 00000000000..6b5891c77ad --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/launches/CDO AllTests (WSS).launch @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsWSS.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsWSS.java new file mode 100644 index 00000000000..80ada357832 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsWSS.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 Eike Stepper (Loehne, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.cdo.tests; + +import org.eclipse.emf.cdo.tests.config.impl.SessionConfig; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * @author Eike Stepper + */ +public class AllTestsWSS extends AllConfigs +{ + public static Test suite() + { + return new AllTestsWSS().getTestSuite(); + } + + @Override + protected void initConfigSuites(TestSuite parent) + { + SessionConfig sessionConfig = WSS; + + addScenario(parent, MEM, sessionConfig, NATIVE); + addScenario(parent, MEM_AUDITS, sessionConfig, NATIVE); + addScenario(parent, MEM_BRANCHES, sessionConfig, NATIVE); + addScenario(parent, MEM_BRANCHES_UUIDS, sessionConfig, NATIVE); + + addScenario(parent, MEM, sessionConfig, LEGACY); + addScenario(parent, MEM_AUDITS, sessionConfig, LEGACY); + addScenario(parent, MEM_BRANCHES, sessionConfig, LEGACY); + } +} diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IConstants.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IConstants.java index a8d3d67e04e..e3ed2103864 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IConstants.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/IConstants.java @@ -45,6 +45,8 @@ public interface IConstants public static final SessionConfig WS = Net4j.WS.INSTANCE; + public static final SessionConfig WSS = Net4j.WSS.INSTANCE; + public static final ModelConfig NATIVE = ModelConfig.Native.INSTANCE; public static final ModelConfig LEGACY = ModelConfig.Legacy.INSTANCE; diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/ISessionConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/ISessionConfig.java index 4084446c601..4427c6065de 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/ISessionConfig.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/ISessionConfig.java @@ -32,6 +32,8 @@ public interface ISessionConfig extends IConfig public static final String CAPABILITY_NET4J_WS = "session.net4j.ws"; + public static final String CAPABILITY_NET4J_WSS = "session.net4j.wss"; + public static final String CAPABILITY_NET4J_EMBEDDED = "session.net4j.embedded"; public IManagedContainer getClientContainer(); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java index ddda1843297..9eaa2601314 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016, 2018-2021 Eike Stepper (Loehne, Germany) and others. + * Copyright (c) 2008-2016, 2018-2021, 2024 Eike Stepper (Loehne, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * Eike Stepper - initial API and implementation * Christian W. Damus (CEA) - don't remove statically registered packages from registry + * Maxime Porhel (Obeo) - WebSocket support adaptation to Jetty 12 */ package org.eclipse.emf.cdo.tests.config.impl; @@ -50,19 +51,29 @@ import org.eclipse.net4j.util.security.IPasswordCredentialsProvider; import org.eclipse.net4j.ws.WSUtil; import org.eclipse.net4j.ws.jetty.Net4jWebSocketServlet; +import org.eclipse.net4j.wss.WSSUtil; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.impl.EPackageImpl; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.jetty.ee8.servlet.ServletContextHandler; +import org.eclipse.jetty.ee8.servlet.ServletHolder; +import org.eclipse.jetty.ee8.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.util.ssl.SslContextFactory; import java.io.File; import java.lang.reflect.Field; import java.net.URI; import java.net.URISyntaxException; +import java.net.URL; import java.util.Date; import java.util.HashSet; import java.util.Set; @@ -813,20 +824,153 @@ public void setUp() throws Exception WSUtil.prepareContainer(getServerContainer()); } + if (server == null) + { + System.out.println("Starting Jetty..."); + server = new Server(HTTP_PORT); + + ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS); + handler.setContextPath("/"); + server.setHandler(handler); + + JettyWebSocketServletContainerInitializer.configure(handler, null); + handler.addServlet(new ServletHolder("net4j", Net4jWebSocketServlet.class), "/net4j"); + + server.start(); + System.out.println("Started Jetty server..."); + } + } + + @Override + public void mainSuiteFinished() throws Exception + { + super.mainSuiteFinished(); + + if (server != null) + { + System.out.println("Stopping Jetty..."); + server.stop(); + server = null; + } + } + + @Override + public CDOViewProvider createViewProvider(final IManagedContainer container) + { + return new CDONet4jViewProvider.WS() + { + @Override + protected IManagedContainer getContainer() + { + return container; + } + }; + } + } + + /** + * @author Maxime Porhel + */ + public static final class WSS extends SessionConfig.Net4j + { + public static final String NAME = "WSS"; + + public static final WSS INSTANCE = new WSS(); + + public static final int HTTPS_PORT = 8433; + + public static final String SERVICE_URI = "wss://localhost:" + HTTPS_PORT + "/net4j"; + + public static final String ACCEPTOR_NAME = "default"; + + private static final long serialVersionUID = 1L; + + private static Server server; + + public WSS() + { + super(NAME); + } + + @Override + public void initCapabilities(Set capabilities) + { + super.initCapabilities(capabilities); + capabilities.add(CAPABILITY_NET4J_WSS); + } + + @Override + public String getURIPrefix() + { + return getURIProtocol() + "://localhost:" + HTTPS_PORT + "/net4j/@" + ACCEPTOR_NAME; + } + + @Override + public IAcceptor getAcceptor() + { + return WSSUtil.getAcceptor(getServerContainer(), ACCEPTOR_NAME); + } + + @Override + public IConnector getConnector() + { + try + { + // System.setProperty("org.eclipse.net4j.wss.ssl.endpointIdentificationAlgorithm", "null"); + // System.setProperty("org.eclipse.net4j.wss.ssl.passphrase", "secret"); + // System.setProperty("org.eclipse.net4j.wss.ssl.trust", new File("ssl/trusted.ks").toURI().toString()); + System.setProperty("org.eclipse.net4j.internal.wss.ssl.trustall", "true"); + + return WSSUtil.getConnector(getClientContainer(), new URI(SERVICE_URI), ACCEPTOR_NAME); + } + catch (URISyntaxException ex) + { + throw new RuntimeException(ex); + } + } + + @Override + public void setUp() throws Exception + { + super.setUp(); + WSSUtil.prepareContainer(getClientContainer()); + + if (!usesServerContainer()) + { + WSSUtil.prepareContainer(getServerContainer()); + } + if (server == null) { System.out.println("Starting Jetty..."); server = new Server(); - ServerConnector connector = new ServerConnector(server); - connector.setPort(HTTP_PORT); - server.addConnector(connector); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + + URL baseurl = org.eclipse.emf.cdo.tests.bundle.OM.BUNDLE.getBaseURL(); + File file = URIUtil.toFile(URIUtil.toURI(baseurl)); + File keyStoreFile = new File(file.getPath() + File.separator + "sslKey" + File.separator + "testKeys"); + sslContextFactory.setKeyStorePath(keyStoreFile.getPath()); + sslContextFactory.setKeyStorePassword("ab987c"); + + HttpConfiguration httpsConfig = new HttpConfiguration(); + httpsConfig.addCustomizer(new SecureRequestCustomizer(false)); + + ServerConnector wssConnector = new ServerConnector(server, new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.toString()), + new HttpConnectionFactory(httpsConfig)); + wssConnector.setHost("localhost"); + wssConnector.setPort(HTTPS_PORT); + server.addConnector(wssConnector); ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS); handler.setContextPath("/"); - handler.addServlet(new ServletHolder("net4j", Net4jWebSocketServlet.class), "/net4j"); server.setHandler(handler); + + JettyWebSocketServletContainerInitializer.configure(handler, null); + handler.addServlet(new ServletHolder("net4j", Net4jWebSocketServlet.class), "/net4j"); + server.start(); + System.out.println("Started Jetty server..."); } } @@ -846,7 +990,7 @@ public void mainSuiteFinished() throws Exception @Override public CDOViewProvider createViewProvider(final IManagedContainer container) { - return new CDONet4jViewProvider.WS() + return new CDONet4jViewProvider.WSS() { @Override protected IManagedContainer getContainer() diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/bundle/OM.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/bundle/OM.java index 82eea936f04..d4a5eec958b 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/bundle/OM.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/bundle/OM.java @@ -102,6 +102,10 @@ public static boolean isCompareSupportAvailable() public static Image getOverlayImage(Object image, Object overlayImage, int x, int y) { + if (image == null) + { + return null; + } ComposedImage composedImage = new OverlayImage(image, overlayImage, x, y); return ExtendedImageRegistry.INSTANCE.getImage(composedImage); } diff --git a/plugins/org.eclipse.net4j.tcp/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j.tcp/META-INF/MANIFEST.MF index 53a93ceec47..6ef45f2b128 100644 --- a/plugins/org.eclipse.net4j.tcp/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.net4j.tcp/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.net4j.tcp;singleton:=true -Bundle-Version: 4.4.1.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -12,13 +12,13 @@ Bundle-ClassPath: . Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)";resolution:=optional, org.eclipse.net4j;bundle-version="[4.0.0,5.0.0)";visibility:=reexport Import-Package: org.osgi.framework;version="[1.3.0,2.0.0)";resolution:=optional -Export-Package: org.eclipse.net4j.internal.tcp;version="4.4.1"; +Export-Package: org.eclipse.net4j.internal.tcp;version="4.4.2"; x-friends:="org.eclipse.net4j.tests, org.eclipse.emf.cdo.examples, org.eclipse.net4j.ui", - org.eclipse.net4j.internal.tcp.bundle;version="4.4.1";x-internal:=true, - org.eclipse.net4j.internal.tcp.messages;version="4.4.1";x-internal:=true, - org.eclipse.net4j.internal.tcp.ssl;version="4.4.1";x-friends:="org.eclipse.net4j.tests,org.eclipse.emf.cdo.examples", - org.eclipse.net4j.tcp;version="4.4.1", - org.eclipse.net4j.tcp.ssl;version="4.4.1" + org.eclipse.net4j.internal.tcp.bundle;version="4.4.2";x-internal:=true, + org.eclipse.net4j.internal.tcp.messages;version="4.4.2";x-internal:=true, + org.eclipse.net4j.internal.tcp.ssl;version="4.4.2";x-friends:="org.eclipse.net4j.tests,org.eclipse.emf.cdo.examples", + org.eclipse.net4j.tcp;version="4.4.2", + org.eclipse.net4j.tcp.ssl;version="4.4.2" Automatic-Module-Name: org.eclipse.net4j.tcp diff --git a/plugins/org.eclipse.net4j.tcp/pom.xml b/plugins/org.eclipse.net4j.tcp/pom.xml index 45da1af58ab..b480e6bf7a7 100644 --- a/plugins/org.eclipse.net4j.tcp/pom.xml +++ b/plugins/org.eclipse.net4j.tcp/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo org.eclipse.net4j.tcp - 4.4.1-SNAPSHOT + 4.4.2-SNAPSHOT eclipse-plugin diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptor.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptor.java index e8dc5de44ab..7e26eb8fc1f 100644 --- a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptor.java +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptor.java @@ -18,6 +18,7 @@ import org.eclipse.net4j.tcp.ITCPSelector; import org.eclipse.net4j.tcp.TCPUtil; import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump; +import org.eclipse.net4j.util.StringUtil; import org.eclipse.net4j.util.concurrent.Worker; import org.eclipse.net4j.util.factory.ProductCreationException; import org.eclipse.net4j.util.io.IOUtil; @@ -329,7 +330,7 @@ public String getAcceptorDescription(Element acceptorConfig) { String listenAddr = acceptorConfig.getAttribute("listenAddr"); //$NON-NLS-1$ String port = acceptorConfig.getAttribute("port"); //$NON-NLS-1$ - return (listenAddr == null ? "" : listenAddr) + (port == null ? "" : ":" + port); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return (listenAddr == null ? "" : listenAddr) + (StringUtil.isEmpty(port) ? "" : ":" + port); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } } diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ssl/SSLAcceptor.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ssl/SSLAcceptor.java index 1f5d337a2c4..858257520c8 100644 --- a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ssl/SSLAcceptor.java +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ssl/SSLAcceptor.java @@ -14,6 +14,7 @@ import org.eclipse.net4j.TransportConfigurator.AcceptorDescriptionParser; import org.eclipse.net4j.internal.tcp.TCPAcceptor; import org.eclipse.net4j.internal.tcp.TCPConnector; +import org.eclipse.net4j.util.StringUtil; import org.eclipse.net4j.util.factory.ProductCreationException; import org.w3c.dom.Element; @@ -66,7 +67,7 @@ public String getAcceptorDescription(Element acceptorConfig) { String listenAddr = acceptorConfig.getAttribute("listenAddr"); //$NON-NLS-1$ String port = acceptorConfig.getAttribute("port"); //$NON-NLS-1$ - return (listenAddr == null ? "" : listenAddr) + (port == null ? "" : ":" + port); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return (listenAddr == null ? "" : listenAddr) + (StringUtil.isEmpty(port) ? "" : ":" + port); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } } diff --git a/plugins/org.eclipse.net4j.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j.tests/META-INF/MANIFEST.MF index 341966250b0..bc298911668 100644 --- a/plugins/org.eclipse.net4j.tests/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.net4j.tests/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.net4j.tests;singleton:=true -Bundle-Version: 4.2.11.qualifier +Bundle-Version: 4.2.12.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -10,36 +10,38 @@ Bundle-Activator: org.eclipse.net4j.tests.bundle.OM$Activator Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ClassPath: . Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)";visibility:=reexport, - org.eclipse.net4j.ws;bundle-version="[1.0.0,2.0.0)";visibility:=reexport, + org.eclipse.net4j.ws;bundle-version="[1.3.0,2.0.0)";visibility:=reexport, org.eclipse.net4j.tcp;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, org.eclipse.net4j.jvm;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, org.apache.log4j;bundle-version="[1.2.0,2.0.0)", org.junit;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, - org.eclipse.jetty.server;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.servlet;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.security;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.client;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.http;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.util;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.io;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.common;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.servlet;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.server;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.client;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.api;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.core.client;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.core.common;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.core.server;bundle-version="[10.0.0,11.0.0)" + org.eclipse.jetty.client;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.http;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.io;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.security;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.server;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.session;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.util;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.security;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.server;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.servlet;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.api;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.common;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.servlet;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.server;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.websocket.core.client;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.websocket.core.common;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.websocket.core.server;bundle-version="[12.0.0,13.0.0)" Import-Package: javax.servlet;version="[2.3.0,5.0.0)", javax.servlet.http;version="[2.3.0,5.0.0)", org.slf4j;version="[1.0.0,2.0.0)" -Export-Package: org.eclipse.net4j.tests;version="4.2.11", - org.eclipse.net4j.tests.apps;version="4.2.11", - org.eclipse.net4j.tests.bugzilla;version="4.2.11", - org.eclipse.net4j.tests.bundle;version="4.2.11";x-internal:=true, - org.eclipse.net4j.tests.config;version="4.2.11", - org.eclipse.net4j.tests.data;version="4.2.11", - org.eclipse.net4j.tests.signal;version="4.2.11", - org.eclipse.net4j.util.tests;version="4.2.11", - org.eclipse.net4j.util.tests.cache;version="4.2.11" +Export-Package: org.eclipse.net4j.tests;version="4.2.12", + org.eclipse.net4j.tests.apps;version="4.2.12", + org.eclipse.net4j.tests.bugzilla;version="4.2.12", + org.eclipse.net4j.tests.bundle;version="4.2.12";x-internal:=true, + org.eclipse.net4j.tests.config;version="4.2.12", + org.eclipse.net4j.tests.data;version="4.2.12", + org.eclipse.net4j.tests.signal;version="4.2.12", + org.eclipse.net4j.util.tests;version="4.2.12", + org.eclipse.net4j.util.tests.cache;version="4.2.12" Automatic-Module-Name: org.eclipse.net4j.tests diff --git a/plugins/org.eclipse.net4j.tests/pom.xml b/plugins/org.eclipse.net4j.tests/pom.xml index 5f0d8cec8af..9efc11db3d8 100644 --- a/plugins/org.eclipse.net4j.tests/pom.xml +++ b/plugins/org.eclipse.net4j.tests/pom.xml @@ -25,7 +25,7 @@ org.eclipse.emf.cdo org.eclipse.net4j.tests - 4.2.11-SNAPSHOT + 4.2.12-SNAPSHOT eclipse-plugin diff --git a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/AllTests.java b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/AllTests.java index a300b6d4547..7eae4631c05 100644 --- a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/AllTests.java +++ b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/AllTests.java @@ -18,6 +18,7 @@ import org.eclipse.net4j.tests.config.TestConfig.SSL; import org.eclipse.net4j.tests.config.TestConfig.TCP; import org.eclipse.net4j.tests.config.TestConfig.WS; +import org.eclipse.net4j.tests.config.TestConfig.WSS; import org.eclipse.net4j.util.tests.ExecutorWorkSerializerTest; import org.eclipse.net4j.util.tests.ExpectedIOTest; import org.eclipse.net4j.util.tests.ExtendedIOTest; @@ -42,7 +43,7 @@ public class AllTests public static Test suite() { @SuppressWarnings("unchecked") - TestSuite suite = new Net4jTestSuite(AllTests.class.getName(), JVM.class, TCP.class, SSL.class, WS.class); + TestSuite suite = new Net4jTestSuite(AllTests.class.getName(), JVM.class, TCP.class, SSL.class, WS.class, WSS.class); populateSuite(suite); return suite; } diff --git a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/bugzilla/Bugzilla_241463_Test.java b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/bugzilla/Bugzilla_241463_Test.java index 442f0562bf1..cece44e9d49 100644 --- a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/bugzilla/Bugzilla_241463_Test.java +++ b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/bugzilla/Bugzilla_241463_Test.java @@ -8,6 +8,7 @@ * Contributors: * Eike Stepper - initial API and implementation * Teerawat Chaiyakijpichet (No Magic Asia Ltd.) - maintenance (SSL) + * Maxime Porhel (Obeo) - WSS Support */ package org.eclipse.net4j.tests.bugzilla; @@ -24,6 +25,7 @@ import org.eclipse.net4j.internal.ws.WSAcceptor; import org.eclipse.net4j.internal.ws.WSAcceptorFactory; import org.eclipse.net4j.internal.ws.WSServerConnector; +import org.eclipse.net4j.internal.wss.WSSAcceptorFactory; import org.eclipse.net4j.tcp.ITCPAcceptor; import org.eclipse.net4j.tcp.ITCPSelector; import org.eclipse.net4j.tests.config.AbstractConfigTest; @@ -51,6 +53,7 @@ protected IManagedContainer createContainer() container.registerFactory(new FakeTCPAcceptorFactory()); container.registerFactory(new FakeSSLAcceptorFactory()); container.registerFactory(new FakeWSAcceptorFactory()); + container.registerFactory(new FakeWSSAcceptorFactory()); return container; } @@ -212,4 +215,31 @@ public InternalChannel inverseOpenChannel(short channelID, String protocolID, in }; } } + + /** + * @author Maxime Porhel + */ + private static final class FakeWSSAcceptorFactory extends WSSAcceptorFactory + { + @Override + protected WSAcceptor createAcceptor() + { + return new WSAcceptor() + { + @Override + protected WSServerConnector createConnector() + { + return new WSServerConnector(this) + { + + @Override + public InternalChannel inverseOpenChannel(short channelID, String protocolID, int protocolVersion) + { + throw new RuntimeException("Simulated problem"); //$NON-NLS-1$ + } + }; + } + }; + } + } } diff --git a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/config/TestConfig.java b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/config/TestConfig.java index 37f5acf6618..fcc3a7e04ab 100644 --- a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/config/TestConfig.java +++ b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/tests/config/TestConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Eike Stepper (Loehne, Germany) and others. + * Copyright (c) 2020, 2022, 2024 Eike Stepper (Loehne, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,8 @@ * Contributors: * Eike Stepper - initial API and implementation * Maxime Porhel (Obeo) - re-enable WebSocket tests after move to Jetty 10.0.12 + * Maxime Porhel (Obeo) - WebSocket support adaptation to Jetty 12 + * Maxime Porhel (Obeo) - WSS Support */ package org.eclipse.net4j.tests.config; @@ -24,6 +26,7 @@ import org.eclipse.net4j.internal.ws.WSAcceptorFactory; import org.eclipse.net4j.internal.ws.WSConnector; import org.eclipse.net4j.internal.ws.WSConnectorFactory; +import org.eclipse.net4j.internal.wss.WSSAcceptorFactory; import org.eclipse.net4j.jvm.IJVMAcceptor; import org.eclipse.net4j.jvm.IJVMConnector; import org.eclipse.net4j.jvm.JVMUtil; @@ -31,21 +34,32 @@ import org.eclipse.net4j.tcp.ITCPConnector; import org.eclipse.net4j.tcp.TCPUtil; import org.eclipse.net4j.tcp.ssl.SSLUtil; +import org.eclipse.net4j.tests.bundle.OM; import org.eclipse.net4j.util.container.IManagedContainer; import org.eclipse.net4j.util.io.IOUtil; import org.eclipse.net4j.ws.IWSAcceptor; import org.eclipse.net4j.ws.IWSConnector; import org.eclipse.net4j.ws.WSUtil; import org.eclipse.net4j.ws.jetty.Net4jWebSocketServlet; - +import org.eclipse.net4j.wss.WSSUtil; + +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.jetty.ee8.servlet.ServletContextHandler; +import org.eclipse.jetty.ee8.servlet.ServletHolder; +import org.eclipse.jetty.ee8.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import java.io.File; import java.io.IOException; import java.net.URISyntaxException; +import java.net.URL; /** * @author Eike Stepper @@ -307,24 +321,135 @@ public void closeUnderlyingConnection(IConnector connector) throws IOException ((WSConnector)connector).getWebSocket().close(); } + @Override + public void setUp() throws Exception + { + IOUtil.OUT().println("Starting Jetty..."); + server = new Server(HTTP_PORT); + + ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS); + handler.setContextPath("/"); + server.setHandler(handler); + + JettyWebSocketServletContainerInitializer.configure(handler, null); + handler.addServlet(new ServletHolder("net4j", Net4jWebSocketServlet.class), "/net4j"); + + server.start(); + System.out.println("Started Jetty server..."); + } + + @Override + public void tearDown() throws Exception + { + IOUtil.OUT().println("Stopping Jetty..."); + server.stop(); + server = null; + } + + @Override + public String toString() + { + return WS.class.getSimpleName(); + } + }; + } + } + + /** + * @author Maxime Porhel + */ + public static class WSS implements Factory + { + public static final int HTTPS_PORT = 8088; + + public static final String SERVICE_URI = "wss://localhost:" + HTTPS_PORT + "/net4j"; + + public static final String ACCEPTOR_NAME = "default"; + + @Override + public TestConfig createConfig() + { + return new TestConfig() + { + private Server server; + + @Override + public boolean needsSeparateContainers() + { + return false; + } + + @Override + public void prepareContainer(IManagedContainer container) + { + WSSUtil.prepareContainer(container); + } + + @Override + public IAcceptor getAcceptor(IManagedContainer container, boolean activate) + { + // SSL context is handled by Jetty. + + return (IWSAcceptor)container.getElement(WSSAcceptorFactory.PRODUCT_GROUP, WSSUtil.FACTORY_TYPE, ACCEPTOR_NAME, activate); + } + + @Override + public IConnector getConnector(IManagedContainer container, boolean activate) + { + try + { + // System.setProperty("org.eclipse.net4j.wss.ssl.endpointIdentificationAlgorithm", "null"); + // System.setProperty("org.eclipse.net4j.wss.ssl.passphrase", "secret"); + // System.setProperty("org.eclipse.net4j.wss.ssl.trust", new File("ssl/trusted.ks").toURI().toString()); + System.setProperty("org.eclipse.net4j.internal.wss.ssl.trustall", "true"); + + String description = WSSUtil.getConnectorDescription(SERVICE_URI, ACCEPTOR_NAME); + return (IWSConnector)container.getElement(WSConnectorFactory.PRODUCT_GROUP, WSSUtil.FACTORY_TYPE, description, activate); + } + catch (URISyntaxException ex) + { + throw new RuntimeException(ex); + } + } + + @Override + public void closeUnderlyingConnection(IConnector connector) throws IOException + { + ((WSConnector)connector).getWebSocket().close(); + } + @Override public void setUp() throws Exception { IOUtil.OUT().println("Starting Jetty..."); server = new Server(); - ServerConnector connector = new ServerConnector(server); - connector.setPort(HTTP_PORT); - server.addConnector(connector); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + + URL baseurl = OM.BUNDLE.getBaseURL(); + File file = URIUtil.toFile(URIUtil.toURI(baseurl)); + File keyStoreFile = new File(file.getPath() + File.separator + "sslKey" + File.separator + "testKeys"); + sslContextFactory.setKeyStorePath(keyStoreFile.getPath()); + sslContextFactory.setKeyStorePassword("ab987c"); + + HttpConfiguration httpsConfig = new HttpConfiguration(); + httpsConfig.addCustomizer(new SecureRequestCustomizer(false)); + + ServerConnector wssConnector = new ServerConnector(server, new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.toString()), + new HttpConnectionFactory(httpsConfig)); + wssConnector.setHost("localhost"); + wssConnector.setPort(HTTPS_PORT); + server.addConnector(wssConnector); ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS); handler.setContextPath("/"); + server.setHandler(handler); JettyWebSocketServletContainerInitializer.configure(handler, null); - handler.addServlet(new ServletHolder("net4j", Net4jWebSocketServlet.class), "/net4j"); - server.setHandler(handler); + server.start(); + System.out.println("Started Jetty server..."); } @Override @@ -338,7 +463,7 @@ public void tearDown() throws Exception @Override public String toString() { - return WS.class.getSimpleName(); + return WSS.class.getSimpleName(); } }; } diff --git a/plugins/org.eclipse.net4j.ws/.settings/.api_filters b/plugins/org.eclipse.net4j.ws/.settings/.api_filters index e5d639a705e..1bbcab8faaa 100644 --- a/plugins/org.eclipse.net4j.ws/.settings/.api_filters +++ b/plugins/org.eclipse.net4j.ws/.settings/.api_filters @@ -7,6 +7,12 @@ + + + + + + @@ -32,7 +38,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -45,4 +78,24 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.eclipse.net4j.ws/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j.ws/META-INF/MANIFEST.MF index 2dbb39eb6a4..7b8599991c1 100644 --- a/plugins/org.eclipse.net4j.ws/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.net4j.ws/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.net4j.ws;singleton:=true -Bundle-Version: 1.2.3.qualifier +Bundle-Version: 1.3.0.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -10,22 +10,29 @@ Bundle-Activator: org.eclipse.net4j.internal.ws.bundle.OM$Activator Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ClassPath: . Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)";resolution:=optional, + org.eclipse.core.net;bundle-version="[1.5.0,1.6.0)", org.eclipse.net4j;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, - org.eclipse.jetty.websocket.server;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.servlet;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.common;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.client;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.websocket.api;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.servlet;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.client;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.http;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.util;bundle-version="[10.0.0,11.0.0)", - org.eclipse.jetty.io;bundle-version="[10.0.0,11.0.0)" + org.eclipse.jetty.client;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.http;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.io;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.util;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.api;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.common;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.client;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.server;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.websocket.servlet;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.security;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.ee8.servlet;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.websocket.core.client;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.websocket.core.common;bundle-version="[12.0.0,13.0.0)", + org.eclipse.jetty.websocket.core.server;bundle-version="[12.0.0,13.0.0)" Import-Package: org.osgi.framework;version="[1.3.0,2.0.0)";resolution:=optional, javax.servlet;version="[2.3.0,5.0.0)", javax.servlet.http;version="[2.3.0,5.0.0)" -Export-Package: org.eclipse.net4j.internal.ws;version="1.2.3";x-friends:="org.eclipse.net4j.tests,org.eclipse.emf.cdo.examples,org.eclipse.net4j.ui", - org.eclipse.net4j.internal.ws.bundle;version="1.2.3";x-internal:=true, - org.eclipse.net4j.ws;version="1.2.3", - org.eclipse.net4j.ws.jetty;version="1.2.3" +Export-Package: org.eclipse.net4j.internal.ws;version="1.3.0";x-friends:="org.eclipse.net4j.tests,org.eclipse.emf.cdo.examples,org.eclipse.net4j.ui", + org.eclipse.net4j.internal.ws.bundle;version="1.3.0";x-internal:=true, + org.eclipse.net4j.ws;version="1.3.0", + org.eclipse.net4j.ws.jetty;version="1.3.0", + org.eclipse.net4j.wss;version="1.3.0", + org.eclipse.net4j.internal.wss;version="1.3.0";x-friends:="org.eclipse.net4j.tests,org.eclipse.emf.cdo.examples,org.eclipse.net4j.ui" Automatic-Module-Name: org.eclipse.net4j.ws diff --git a/plugins/org.eclipse.net4j.ws/plugin.xml b/plugins/org.eclipse.net4j.ws/plugin.xml index 5d077b02489..7028c4604e5 100644 --- a/plugins/org.eclipse.net4j.ws/plugin.xml +++ b/plugins/org.eclipse.net4j.ws/plugin.xml @@ -1,7 +1,7 @@ @@ -17,6 +18,10 @@ + + + + diff --git a/plugins/org.eclipse.net4j.ws/pom.xml b/plugins/org.eclipse.net4j.ws/pom.xml index 02ee125a52a..eec4880cc45 100644 --- a/plugins/org.eclipse.net4j.ws/pom.xml +++ b/plugins/org.eclipse.net4j.ws/pom.xml @@ -17,15 +17,14 @@ 4.0.0 - org.eclipse.emf.cdo + org.eclipse.emf.cdo org.eclipse.emf.cdo.plugins 4.7.0-SNAPSHOT ../../releng/org.eclipse.emf.cdo.releng.parent/plugins - org.eclipse.emf.cdo org.eclipse.net4j.ws - 1.2.3-SNAPSHOT + 1.3.0-SNAPSHOT eclipse-plugin diff --git a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSAcceptor.java b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSAcceptor.java index 229330b11c7..5063a44f9a9 100644 --- a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSAcceptor.java +++ b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSAcceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Eike Stepper (Loehne, Germany) and others. + * Copyright (c) 2020, 2024 Eike Stepper (Loehne, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Maxime Porhel (Obeo) - WSS Support */ package org.eclipse.net4j.internal.ws; @@ -35,6 +36,8 @@ public class WSAcceptor extends Acceptor implements IWSAcceptor private String name; + private String type = WSUtil.FACTORY_TYPE; + public WSAcceptor() { } @@ -51,6 +54,12 @@ public void setName(String name) this.name = name; } + public void setType(String type) + { + checkInactive(); + this.type = type; + } + public WSServerConnector handleAccept(Net4jWebSocket webSocket) { WSServerConnector connector = createConnector(); @@ -64,6 +73,10 @@ public WSServerConnector handleAccept(Net4jWebSocket webSocket) @Override public String toString() { + if (!WSUtil.FACTORY_TYPE.equalsIgnoreCase(type)) + { + return MessageFormat.format("WSAcceptor[{0}, {1}]", type, name); //$NON-NLS-1$ + } return MessageFormat.format("WSAcceptor[{0}]", name); //$NON-NLS-1$ } diff --git a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSAcceptorFactory.java b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSAcceptorFactory.java index cd2c9a85204..e94eea5311d 100644 --- a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSAcceptorFactory.java +++ b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSAcceptorFactory.java @@ -10,6 +10,7 @@ */ package org.eclipse.net4j.internal.ws; +import org.eclipse.net4j.util.StringUtil; import org.eclipse.net4j.ws.IWSAcceptor; import org.eclipse.net4j.ws.WSUtil; @@ -20,6 +21,12 @@ */ public class WSAcceptorFactory extends AcceptorFactory { + + /** + * Default acceptor name when acceptor tag in cdo-server.xml does not declare a listen address. + */ + public static final String DEFAULT_ACCEPTOR_NAME = "default"; //$NON-NLS-1$ + public WSAcceptorFactory() { super(WSUtil.FACTORY_TYPE); @@ -37,7 +44,14 @@ protected WSAcceptorFactory(String type) public WSAcceptor create(String description) { WSAcceptor acceptor = createAcceptor(); - acceptor.setName(description); + if (StringUtil.isEmpty(description)) + { + acceptor.setName(DEFAULT_ACCEPTOR_NAME); + } + else + { + acceptor.setName(description); + } return acceptor; } diff --git a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSClientConnector.java b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSClientConnector.java index e25aad9afbb..561037f8c7d 100644 --- a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSClientConnector.java +++ b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSClientConnector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021 Eike Stepper (Loehne, Germany) and others. + * Copyright (c) 2020, 2024 Eike Stepper (Loehne, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,20 +7,40 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Maxime Porhel (Obeo) - WSS Support */ package org.eclipse.net4j.internal.ws; +import org.eclipse.net4j.util.StringUtil; +import org.eclipse.net4j.util.om.OMPlatform; import org.eclipse.net4j.ws.jetty.Net4jWebSocket; +import org.eclipse.core.net.proxy.IProxyData; +import org.eclipse.core.net.proxy.IProxyService; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; -import org.eclipse.jetty.websocket.client.WebSocketClient; - +import org.eclipse.jetty.client.BasicAuthentication; +import org.eclipse.jetty.client.BasicAuthentication.BasicResult; +import org.eclipse.jetty.client.HttpProxy; +import org.eclipse.jetty.client.Origin.Address; +import org.eclipse.jetty.client.ProxyConfiguration.Proxy; +import org.eclipse.jetty.ee8.websocket.api.Session; +import org.eclipse.jetty.ee8.websocket.client.ClientUpgradeRequest; +import org.eclipse.jetty.ee8.websocket.client.WebSocketClient; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.util.tracker.ServiceTracker; + +import java.net.HttpCookie; import java.net.URI; import java.net.URISyntaxException; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -31,10 +51,11 @@ public class WSClientConnector extends WSConnector { // private static final long CLIENT_IDLE_TIMEOUT = // OMPlatform.INSTANCE.getProperty("org.eclipse.net4j.internal.ws.WSClientConnector.clientIdleTimeout", 30000); + private static final String CLIENT_BASIC_AUTH = "org.eclipse.net4j.internal.ws.WSClientConnector.clientBasicAuth"; private WebSocketClient client; - private boolean ownedClient; + protected boolean ownedClient; private long connectTimeout = 5000; @@ -44,8 +65,11 @@ public class WSClientConnector extends WSConnector private String acceptorName; + private final List cookies; + public WSClientConnector() { + cookies = new ArrayList<>(); } @Override @@ -94,6 +118,10 @@ public String getURL() return url; } + /** + * Compute and set the service uri and the acceptor name from he provided url. + * Must be called before activation (before the calls to doBeforeActivate() and doActivate()). + */ public void setURL(String url) throws URISyntaxException { checkInactive(); @@ -118,6 +146,26 @@ public void setURL(String url) throws URISyntaxException acceptorName = path.segment(index).substring(ACCEPTOR_NAME_PREFIX.length()); } + /** + * Clear known cookies and use the new ones. + */ + public void setCookies(List httpCookies) + { + cookies.clear(); + if (httpCookies != null && !httpCookies.isEmpty()) + { + cookies.addAll(httpCookies); + } + } + + /** + * Return an unmodifiable list of cookies. + */ + public List getCookies() + { + return Collections.unmodifiableList(cookies); + } + @Override public String toString() { @@ -137,17 +185,70 @@ protected int getAcceptorSegmentIndex(IPath path) return -1; } - @Override - protected void doBeforeActivate() throws Exception + /** + * Configures the proxy if necessary, according to org.eclipse.core.net settings. + * @param securedClient the WebSocketClient to configure + */ + protected void configureProxy(WebSocketClient client, String proxyType) { - if (client == null) + Optional service = getProxyService(); + if (service.isPresent()) { - client = new WebSocketClient(); - ownedClient = true; + if (service.get().isProxiesEnabled() && !StringUtil.isEmpty(proxyType)) + { + IProxyData proxyData = service.get().getProxyData(proxyType); + if (proxyData != null && proxyData.getHost() != null) + { + Address address = new Address(proxyData.getHost(), proxyData.getPort()); + Proxy proxy = new HttpProxy(address, false); + if (proxyData.isRequiresAuthentication()) + { + // configure auth if necessary + BasicAuthentication auth = new BasicAuthentication(proxy.getURI(), "<>", //$NON-NLS-1$ + proxyData.getUserId(), proxyData.getPassword()); + client.getHttpClient().getAuthenticationStore().addAuthentication(auth); + client.getHttpClient().getAuthenticationStore() + .addAuthenticationResult(new BasicAuthentication.BasicResult(proxy.getURI(), proxyData.getUserId(), proxyData.getPassword())); + } + client.getHttpClient().getProxyConfiguration().getProxies().add(proxy); + } + } } + } - super.doBeforeActivate(); + private Optional getProxyService() + { + IProxyService service = null; + Bundle bundle = FrameworkUtil.getBundle(org.eclipse.core.runtime.Plugin.class); + BundleContext bundleContext = bundle != null ? bundle.getBundleContext() : null; + if (bundleContext != null) + { + ServiceTracker tracker = new ServiceTracker<>(bundleContext, IProxyService.class, null); + tracker.open(); + service = tracker.getService(); + tracker.close(); + } + return Optional.ofNullable(service); + } + + protected void configureBasicAuthentication(WebSocketClient client) + { + // If the Net4jWebsocketServlet is deployed on path for which the Jetty instance requires basic authentication. + String property = OMPlatform.INSTANCE.getProperty(CLIENT_BASIC_AUTH + ".login"); + if (!StringUtil.isEmpty(property)) + { + // BasicAuthentication auth = new BasicAuthentication(serviceURI, "<>", login, mdp); + // client.getHttpClient().getAuthenticationStore().addAuthentication(auth); + BasicResult basicResult = new BasicAuthentication.BasicResult(serviceURI, property, OMPlatform.INSTANCE.getProperty(CLIENT_BASIC_AUTH + ".password", "")); + client.getHttpClient().getAuthenticationStore().addAuthenticationResult(basicResult); + } + } + + @Override + protected void doBeforeActivate() throws Exception + { + // setURL must be called during cr if (serviceURI == null) { throw new IllegalStateException("serviceURI is null"); //$NON-NLS-1$ @@ -157,6 +258,17 @@ protected void doBeforeActivate() throws Exception { throw new IllegalStateException("acceptorName is null or empty"); //$NON-NLS-1$ } + + if (client == null) + { + client = new WebSocketClient(); + configureProxy(client, IProxyData.HTTP_PROXY_TYPE); + configureBasicAuthentication(client); + ownedClient = true; + } + + super.doBeforeActivate(); + } @Override @@ -177,8 +289,28 @@ protected void doActivate() throws Exception ClientUpgradeRequest request = new ClientUpgradeRequest(); request.setHeader(ACCEPTOR_NAME_HEADER, acceptorName); - Future result = client.connect(webSocket, serviceURI, request); - result.get(connectTimeout, TimeUnit.MILLISECONDS); + if (cookies != null) + { + for (HttpCookie cookie : cookies) + { + request.getCookies().add(cookie); + } + } + + try + { + Future result = client.connect(webSocket, serviceURI, request); + result.get(connectTimeout, TimeUnit.MILLISECONDS); + } + catch (Exception e) + { + if (ownedClient && client != null) + { + client.stop(); + client = null; + } + throw e; + } } @Override @@ -186,7 +318,7 @@ protected void doDeactivate() throws Exception { super.doDeactivate(); - if (ownedClient) + if (ownedClient && client != null) { client.stop(); client = null; diff --git a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSConnectorFactory.java b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSConnectorFactory.java index 457f92b4579..dcd17663f5a 100644 --- a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSConnectorFactory.java +++ b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/ws/WSConnectorFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Eike Stepper (Loehne, Germany) and others. + * Copyright (c) 2020, 2024 Eike Stepper (Loehne, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,25 +7,35 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Maxime Porhel (Obeo) - WSS Support */ package org.eclipse.net4j.internal.ws; import org.eclipse.net4j.util.factory.ProductCreationException; +import org.eclipse.net4j.ws.WSUtil; import org.eclipse.spi.net4j.ConnectorFactory; +import java.net.HttpCookie; import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; /** * @author Eike Stepper */ public class WSConnectorFactory extends ConnectorFactory { - public static final String TYPE = "ws"; //$NON-NLS-1$ + + /** Description token separator. */ + public static final String TOKEN_SEPARATOR = "\n"; + + /** Prefix in description token to signal a cookie definition. */ + public static final String COOKIE_TOKEN_PREFIX = "cookie:"; public WSConnectorFactory() { - super(TYPE); + super(WSUtil.FACTORY_TYPE); } /** @@ -39,17 +49,43 @@ protected WSConnectorFactory(String type) @Override public WSClientConnector create(String description) throws ProductCreationException { + List cookies = new ArrayList<>(); + String[] descriptionTokens = description.split(TOKEN_SEPARATOR); + String urlDescription = descriptionTokens[0]; // URL is always the first token + for (int i = 1; i < descriptionTokens.length; i++) + { + String token = descriptionTokens[i]; + if (token.startsWith(COOKIE_TOKEN_PREFIX)) + { + String cookieString = token.replaceFirst(COOKIE_TOKEN_PREFIX, ""); + int index = cookieString.indexOf("="); + if (index < 1) + { + throw new ProductCreationException("Invalid cookie token: " + token); + } + String name = cookieString.substring(0, index); + String value = cookieString.substring(index + 1); + cookies.add(new HttpCookie(name, value)); + } + else + { + throw new ProductCreationException("Unrecognized description token: " + token); + } + } + WSClientConnector connector = createConnector(); try { - connector.setURL(getType() + "://" + description); //$NON-NLS-1$ + connector.setURL(getType() + "://" + urlDescription); //$NON-NLS-1$ } catch (URISyntaxException ex) { throw new ProductCreationException(ex); } + connector.setCookies(cookies); + return connector; } @@ -65,7 +101,23 @@ public String getDescriptionFor(Object object) if (object instanceof WSConnector) { WSConnector connector = (WSConnector)object; - return connector.getURL(); + String description = connector.getURL(); + + if (connector instanceof WSClientConnector) + { + WSClientConnector clientConnector = (WSClientConnector)connector; + StringBuilder sb = new StringBuilder(description); + for (HttpCookie cookie : clientConnector.getCookies()) + { + sb.append(TOKEN_SEPARATOR); + sb.append(COOKIE_TOKEN_PREFIX); + sb.append(cookie.getName()); + sb.append("="); + sb.append(cookie.getValue()); + } + description = sb.toString(); + } + return description; } return null; diff --git a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/wss/WSSAcceptorFactory.java b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/wss/WSSAcceptorFactory.java new file mode 100644 index 00000000000..f5abf127b4a --- /dev/null +++ b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/wss/WSSAcceptorFactory.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024 Obeo and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maxime Porhel (Obeo) - initial API and implementation + */ +package org.eclipse.net4j.internal.wss; + +import org.eclipse.net4j.TransportConfigurator.AcceptorDescriptionParser; +import org.eclipse.net4j.internal.ws.WSAcceptor; +import org.eclipse.net4j.internal.ws.WSAcceptorFactory; +import org.eclipse.net4j.util.factory.ProductCreationException; +import org.eclipse.net4j.wss.WSSUtil; + +import org.w3c.dom.Element; + +/** + * @author mporhel + */ +public class WSSAcceptorFactory extends WSAcceptorFactory +{ + public WSSAcceptorFactory() + { + super(WSSUtil.FACTORY_TYPE); + } + + /** + * Allows derived classes to override the TYPE identifier + */ + protected WSSAcceptorFactory(String type) + { + super(type); + } + + @Override + protected WSAcceptor createAcceptor() + { + WSAcceptor wsAcceptor = new WSAcceptor(); + wsAcceptor.setType(WSSUtil.FACTORY_TYPE); + return wsAcceptor; + } + + public static class DescriptionParserFactory extends AcceptorDescriptionParser.Factory implements AcceptorDescriptionParser + { + public DescriptionParserFactory() + { + super(WSSUtil.FACTORY_TYPE); + } + + @Override + public AcceptorDescriptionParser create(String description) throws ProductCreationException + { + return this; + } + + @Override + public String getAcceptorDescription(Element acceptorConfig) + { + return acceptorConfig.getAttribute("name"); //$NON-NLS-1$ + } + } +} diff --git a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/wss/WSSClientConnector.java b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/wss/WSSClientConnector.java new file mode 100644 index 00000000000..570e27edb75 --- /dev/null +++ b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/wss/WSSClientConnector.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2024 Obeo and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maxime Porhel (Obeo) - initial API and implementation + */ +package org.eclipse.net4j.internal.wss; + +import org.eclipse.net4j.internal.ws.WSClientConnector; +import org.eclipse.net4j.util.StringUtil; +import org.eclipse.net4j.wss.WSSUtil; + +import org.eclipse.core.net.proxy.IProxyData; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.transport.HttpClientTransportDynamic; +import org.eclipse.jetty.ee8.websocket.client.WebSocketClient; +import org.eclipse.jetty.io.ClientConnector; +import org.eclipse.jetty.util.resource.PathResourceFactory; +import org.eclipse.jetty.util.ssl.SslContextFactory; + +import java.io.File; +import java.net.URI; +import java.text.MessageFormat; + +/** + * @author mporhel + */ +public class WSSClientConnector extends WSClientConnector +{ + + @Override + public String toString() + { + return MessageFormat.format("WSSClientConnector[{0}]", getURL()); //$NON-NLS-1$ + } + + @Override + protected void doBeforeActivate() throws Exception + { + + if (getServiceURI().getScheme().equals(WSSUtil.FACTORY_TYPE)) + { + SslContextFactory.Client sslContextFactory = createSslContextFactory(); + + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setSslContextFactory(sslContextFactory); + + HttpClient httpClient = new HttpClient(new HttpClientTransportDynamic(clientConnector)); + + WebSocketClient securedClient = new WebSocketClient(httpClient); + configureProxy(securedClient, IProxyData.HTTPS_PROXY_TYPE); + configureBasicAuthentication(securedClient); + setClient(securedClient); + + // Let WSClientConnector manage the WebSocketClient, see WSClientConnector::doActivate/doDeactivate + ownedClient = true; + + super.doBeforeActivate(); + } + else + { + throw new IllegalArgumentException("Service Uri should have wss:// scheme"); + } + + } + + private SslContextFactory.Client createSslContextFactory() + { + // initialize SSL Context + SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(); + + boolean trustAll = Boolean.getBoolean("org.eclipse.net4j.internal.wss.ssl.trustall"); + String eia = System.getProperty("org.eclipse.net4j.internal.wss.ssl.endpointIdentificationAlgorithm"); + + String passphrase = System.getProperty("org.eclipse.net4j.internal.wss.ssl.passphrase"); + String trusturi = System.getProperty("org.eclipse.net4j.internal.wss.ssl.trust"); + String trustType = System.getProperty("org.eclipse.net4j.internal.wss.ssl.trust.type"); + String trustAlg = System.getProperty("org.eclipse.net4j.internal.wss.ssl.trust.manager.factory.algorithm"); + + sslContextFactory.setTrustAll(trustAll); + + if ("null".equals(eia)) + { + sslContextFactory.setEndpointIdentificationAlgorithm(null); + } + else if (!StringUtil.isEmpty(eia)) + { + sslContextFactory.setEndpointIdentificationAlgorithm(eia); + } + + if (trusturi != null) + { + URI uri = URI.create(trusturi); + File file = new File(uri); + if (file.exists()) + { + sslContextFactory.setTrustStoreResource(new PathResourceFactory().newResource(uri)); + sslContextFactory.setTrustStorePassword(passphrase); + if (!StringUtil.isEmpty(trustType)) + { + sslContextFactory.setTrustStoreType(trustType); + } + + if (!StringUtil.isEmpty(trustAlg)) + { + sslContextFactory.setTrustManagerFactoryAlgorithm(trustAlg); + } + } + } + return sslContextFactory; + } + +} diff --git a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/wss/WSSConnectorFactory.java b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/wss/WSSConnectorFactory.java new file mode 100644 index 00000000000..e58fc42e927 --- /dev/null +++ b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/internal/wss/WSSConnectorFactory.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Obeo and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maxime Porhel (Obeo) - initial API and implementation + */ +package org.eclipse.net4j.internal.wss; + +import org.eclipse.net4j.internal.ws.WSClientConnector; +import org.eclipse.net4j.internal.ws.WSConnectorFactory; +import org.eclipse.net4j.wss.WSSUtil; + +/** + * @author mporhel + */ +public class WSSConnectorFactory extends WSConnectorFactory +{ + public WSSConnectorFactory() + { + super(WSSUtil.FACTORY_TYPE); + } + + @Override + protected WSClientConnector createConnector() + { + return new WSSClientConnector(); + } +} diff --git a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/WSUtil.java b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/WSUtil.java index 5255567c021..0c0138d6244 100644 --- a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/WSUtil.java +++ b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/WSUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023 Eike Stepper (Loehne, Germany) and others. + * Copyright (c) 2020, 2024 Eike Stepper (Loehne, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Maxime Porhel (Obeo) - WSS Support */ package org.eclipse.net4j.ws; @@ -46,18 +47,27 @@ public static IWSConnector getConnector(IManagedContainer container, String desc return (IWSConnector)container.getElement(WSConnectorFactory.PRODUCT_GROUP, FACTORY_TYPE, description); } - public static IWSConnector getConnector(IManagedContainer container, URI serviceURI, String acceptorName) + /** + * @since 1.3 + */ + public static IWSConnector getConnector(IManagedContainer container, URI serviceURI, String acceptorName, String... arguments) { - String description = getConnectorDescription(serviceURI, acceptorName); + String description = getConnectorDescription(serviceURI, acceptorName, arguments); return getConnector(container, description); } - public static String getConnectorDescription(String serviceURI, String acceptorName) throws URISyntaxException + /** + * @since 1.3 + */ + public static String getConnectorDescription(String serviceURI, String acceptorName, String... arguments) throws URISyntaxException { - return getConnectorDescription(new URI(serviceURI), acceptorName); + return getConnectorDescription(new URI(serviceURI), acceptorName, arguments); } - public static String getConnectorDescription(URI serviceURI, String acceptorName) + /** + * @since 1.3 + */ + public static String getConnectorDescription(URI serviceURI, String acceptorName, String... arguments) { String string = serviceURI.toString(); if (!string.endsWith("/")) //$NON-NLS-1$ @@ -76,6 +86,12 @@ public static String getConnectorDescription(URI serviceURI, String acceptorName } URI uri = serviceURI.resolve(IWSConnector.ACCEPTOR_NAME_PREFIX + acceptorName); - return uri.getAuthority() + uri.getPath(); + StringBuilder description = new StringBuilder(); + description.append(uri.getAuthority()).append(uri.getPath()); + for (String argument : arguments) + { + description.append(WSConnectorFactory.TOKEN_SEPARATOR).append(argument); + } + return description.toString(); } } diff --git a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/jetty/Net4jWebSocket.java b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/jetty/Net4jWebSocket.java index 9813cfe697a..396710b97e4 100644 --- a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/jetty/Net4jWebSocket.java +++ b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/jetty/Net4jWebSocket.java @@ -31,9 +31,9 @@ import org.eclipse.net4j.util.security.NegotiationException; import org.eclipse.net4j.ws.IWSConnector; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.WebSocketListener; -import org.eclipse.jetty.websocket.api.WriteCallback; +import org.eclipse.jetty.ee8.websocket.api.Session; +import org.eclipse.jetty.ee8.websocket.api.WebSocketListener; +import org.eclipse.jetty.ee8.websocket.api.WriteCallback; import org.eclipse.spi.net4j.InternalChannel; import java.io.IOException; diff --git a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/jetty/Net4jWebSocketServlet.java b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/jetty/Net4jWebSocketServlet.java index c29dd786ebd..284fd28b260 100644 --- a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/jetty/Net4jWebSocketServlet.java +++ b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/ws/jetty/Net4jWebSocketServlet.java @@ -10,8 +10,8 @@ */ package org.eclipse.net4j.ws.jetty; -import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; -import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; +import org.eclipse.jetty.ee8.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.ee8.websocket.server.JettyWebSocketServletFactory; /** * @author Eike Stepper diff --git a/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/wss/WSSUtil.java b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/wss/WSSUtil.java new file mode 100644 index 00000000000..9629f8d2199 --- /dev/null +++ b/plugins/org.eclipse.net4j.ws/src/org/eclipse/net4j/wss/WSSUtil.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024 Obeo and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maxime Porhel (Obeo) - initial API and implementation + */ +package org.eclipse.net4j.wss; + +import org.eclipse.net4j.internal.ws.WSAcceptorFactory; +import org.eclipse.net4j.internal.ws.WSConnectorFactory; +import org.eclipse.net4j.internal.wss.WSSAcceptorFactory; +import org.eclipse.net4j.internal.wss.WSSConnectorFactory; +import org.eclipse.net4j.util.container.IManagedContainer; +import org.eclipse.net4j.ws.IWSAcceptor; +import org.eclipse.net4j.ws.IWSConnector; +import org.eclipse.net4j.ws.WSUtil; + +import java.net.URI; +import java.net.URISyntaxException; + +/** + * A utility class with static convenience methods. + * + * @author mporhel + * @since 1.3 + */ +public final class WSSUtil +{ + public static final String FACTORY_TYPE = "wss"; //$NON-NLS-1$ + + private WSSUtil() + { + } + + public static void prepareContainer(IManagedContainer container) + { + container.registerFactory(new WSSAcceptorFactory()); + container.registerFactory(new WSSConnectorFactory()); + } + + public static IWSAcceptor getAcceptor(IManagedContainer container, String acceptorName) + { + return (IWSAcceptor)container.getElement(WSAcceptorFactory.PRODUCT_GROUP, FACTORY_TYPE, acceptorName); + } + + public static IWSConnector getConnector(IManagedContainer container, String description) + { + return (IWSConnector)container.getElement(WSConnectorFactory.PRODUCT_GROUP, FACTORY_TYPE, description); + } + + public static IWSConnector getConnector(IManagedContainer container, URI serviceURI, String acceptorName, String... arguments) + { + String description = getConnectorDescription(serviceURI, acceptorName, arguments); + return getConnector(container, description); + } + + public static String getConnectorDescription(String serviceURI, String acceptorName, String... arguments) throws URISyntaxException + { + return getConnectorDescription(new URI(serviceURI), acceptorName, arguments); + } + + public static String getConnectorDescription(URI serviceURI, String acceptorName, String... arguments) + { + return WSUtil.getConnectorDescription(serviceURI, acceptorName, arguments); + } +} diff --git a/releng/org.eclipse.emf.cdo.releng.parent/pom.xml b/releng/org.eclipse.emf.cdo.releng.parent/pom.xml index 3aa8adbad93..92c926bb5ad 100644 --- a/releng/org.eclipse.emf.cdo.releng.parent/pom.xml +++ b/releng/org.eclipse.emf.cdo.releng.parent/pom.xml @@ -153,6 +153,7 @@ Eike Stepper - initial API and implementation target-platform-configuration ${tycho-version} + consider org.eclipse.emf.cdo diff --git a/releng/org.eclipse.emf.cdo.releng.parent/tp/org.eclipse.emf.cdo.releng.tp.target b/releng/org.eclipse.emf.cdo.releng.parent/tp/org.eclipse.emf.cdo.releng.tp.target index b832e5a6dbb..583aff8a53b 100644 --- a/releng/org.eclipse.emf.cdo.releng.parent/tp/org.eclipse.emf.cdo.releng.tp.target +++ b/releng/org.eclipse.emf.cdo.releng.parent/tp/org.eclipse.emf.cdo.releng.tp.target @@ -55,26 +55,26 @@ + + + + + + + - - - - - - - @@ -105,12 +105,22 @@ - + + + + + org.apache.aries.spifly + org.apache.aries.spifly.dynamic.bundle + 1.3.3 + jar + + + diff --git a/releng/org.eclipse.emf.cdo.releng/CDO.setup b/releng/org.eclipse.emf.cdo.releng/CDO.setup index 0c776a209a8..5aad787da95 100644 --- a/releng/org.eclipse.emf.cdo.releng/CDO.setup +++ b/releng/org.eclipse.emf.cdo.releng/CDO.setup @@ -258,7 +258,7 @@ - org.eclipse.orbit.mongodb, org.slf4j.api, org.apache.commons.lang, org.apache.log4j, org.eclipse.jetty.websocket.server, org.eclipse.jetty.websocket.client + org.eclipse.orbit.mongodb, org.slf4j.api, org.apache.commons.lang, org.apache.log4j, org.eclipse.jetty.ee8.websocket.server, org.eclipse.jetty.ee8.websocket.client @@ -318,7 +318,7 @@ + url="https://download.eclipse.org/tools/orbit/simrel/maven-jetty/release/12.0.11"/>