Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Reckord2020-08-10 15:49:12 +0000
committerCarsten Reckord2020-09-01 17:13:48 +0000
commit0d8562954756146de11cdd9a55fe37269bfad1e1 (patch)
treee0952b1dd7db977a6a2ba758d90708407b38c6d0
parentff00246e18c568b4b7738581eabfd89e2caff27c (diff)
downloadorg.eclipse.epp.mpc-0d8562954756146de11cdd9a55fe37269bfad1e1.tar.gz
org.eclipse.epp.mpc-0d8562954756146de11cdd9a55fe37269bfad1e1.tar.xz
org.eclipse.epp.mpc-0d8562954756146de11cdd9a55fe37269bfad1e1.zip
Bug 560084: Improve startup up time of Marketplace client
Refactored HTTP and Transport layer initialization. Everything is lazy and service-based now. Change-Id: Idb30512068932c87f905dfaf299ac7db5bec7662 Signed-off-by: Carsten Reckord <reckord@yatta.de>
-rw-r--r--org.eclipse.epp.mpc-target/staging.target2
-rw-r--r--org.eclipse.epp.mpc.core/.settings/org.eclipse.pde.ds.annotations.prefs8
-rw-r--r--org.eclipse.epp.mpc.core/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-transport.xml19
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-wrapper-factory.xml1
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/legacy-transport-factory.xml21
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.debug.options.xml8
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.http.client.factory.xml8
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.http.client.xml9
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.servicehelper.xml8
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.servicelocator.xml8
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.transport.http.factory.xml (renamed from org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-transport-factory.xml)17
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.transport.http.xml9
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.transportfactory.legacy.xml9
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.unmarshaller.xml7
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/service-locator.xml19
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/unmarshaller.xml19
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/MarketplaceClientCorePlugin.java128
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceHelperImpl.java154
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceLocator.java68
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java57
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceUnmarshaller.java2
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/UserFavoritesService.java44
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientFactory.java457
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientService.java198
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientTransport.java51
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientTransportFactory.java7
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpServiceContext.java59
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/NTLMDomainUtil.java (renamed from org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientProxyUtil.java)62
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/RequestTemplate.java93
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/SystemCredentialsProvider.java6
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/FallbackTransportFactory.java48
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/HttpUtil.java57
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ProxyAuthenticator.java194
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ProxyHelper.java81
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ServiceUtil.java8
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/TransportFactory.java50
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceHelper.java4
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/util/TransportFactoryTest.java68
39 files changed, 1051 insertions, 1018 deletions
diff --git a/org.eclipse.epp.mpc-target/staging.target b/org.eclipse.epp.mpc-target/staging.target
index 8cc4d20e..346b455c 100644
--- a/org.eclipse.epp.mpc-target/staging.target
+++ b/org.eclipse.epp.mpc-target/staging.target
@@ -16,7 +16,7 @@
<unit id="org.hamcrest.library" version="0.0.0"/>
<unit id="org.junit" version="0.0.0"/>
<unit id="org.mockito" version="0.0.0"/>
-<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20200128200239/repository"/>
+<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20200826182026/repository"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.epp.mpc.apache.httpclient.feature.feature.group" version="0.0.0"/>
diff --git a/org.eclipse.epp.mpc.core/.settings/org.eclipse.pde.ds.annotations.prefs b/org.eclipse.epp.mpc.core/.settings/org.eclipse.pde.ds.annotations.prefs
new file mode 100644
index 00000000..9eb1c5f3
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/.settings/org.eclipse.pde.ds.annotations.prefs
@@ -0,0 +1,8 @@
+classpath=true
+dsVersion=V1_3
+eclipse.preferences.version=1
+enabled=true
+generateBundleActivationPolicyLazy=true
+path=OSGI-INF/services
+validationErrorLevel=error
+validationErrorLevel.missingImplicitUnbindMethod=error
diff --git a/org.eclipse.epp.mpc.core/META-INF/MANIFEST.MF b/org.eclipse.epp.mpc.core/META-INF/MANIFEST.MF
index 0f29415a..08c87dad 100644
--- a/org.eclipse.epp.mpc.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.epp.mpc.core/META-INF/MANIFEST.MF
@@ -62,7 +62,6 @@ Import-Package: org.apache.http;version="4.4.0",
org.apache.http.client;version="4.5.2",
org.apache.http.client.config;version="4.5.2",
org.apache.http.client.entity;version="4.5.2",
- org.apache.http.client.fluent;version="4.5.2",
org.apache.http.client.methods;version="4.5.2",
org.apache.http.client.protocol;version="4.5.2",
org.apache.http.config;version="4.4.0",
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-transport.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-transport.xml
deleted file mode 100644
index bb17fe43..00000000
--- a/org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-transport.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014, 2018 The Eclipse Foundation and others.
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Eclipse Public License v2.0
- which accompanies this distribution, and is available at
- https://www.eclipse.org/legal/epl-2.0/
-
- SPDX-License-Identifier: EPL-2.0
-
- Contributors:
- The Eclipse Foundation - initial API and implementation
- -->
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.core.transport.http">
- <implementation class="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientTransport"/>
- <service>
- <provide interface="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientTransport"/>
- </service>
-</scr:component>
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-wrapper-factory.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-wrapper-factory.xml
index 3e11f5fe..efe2a3b0 100644
--- a/org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-wrapper-factory.xml
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-wrapper-factory.xml
@@ -17,4 +17,5 @@
<provide interface="org.eclipse.epp.mpc.core.service.ITransportFactory"/>
</service>
<reference bind="bindPrimaryFactory" cardinality="1..1" interface="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientTransportFactory" name="org.eclipse.epp.mpc.core.transport.http.factory" policy="static" unbind="unbindPrimaryFactory"/>
+ <property name="service.ranking" type="Integer" value="1"/>
</scr:component>
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/legacy-transport-factory.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/legacy-transport-factory.xml
deleted file mode 100644
index 307fd431..00000000
--- a/org.eclipse.epp.mpc.core/OSGI-INF/services/legacy-transport-factory.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014, 2018 The Eclipse Foundation and others.
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Eclipse Public License v2.0
- which accompanies this distribution, and is available at
- https://www.eclipse.org/legal/epl-2.0/
-
- SPDX-License-Identifier: EPL-2.0
-
- Contributors:
- The Eclipse Foundation - initial API and implementation
- -->
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.core.transportfactory.legacy">
- <implementation class="org.eclipse.epp.internal.mpc.core.util.TransportFactory$LegacyFactory"/>
- <service>
- <provide interface="org.eclipse.epp.mpc.core.service.ITransportFactory"/>
- </service>
- <property name="org.eclipse.epp.mpc.core.service.transport.legacy" type="Boolean" value="true"/>
- <property name="service.ranking" type="Integer" value="-2147483647"/>
-</scr:component>
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.debug.options.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.debug.options.xml
new file mode 100644
index 00000000..f4fc55d5
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.debug.options.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.core.debug.options">
+ <property name="listener.symbolic.name" value="org.eclipse.epp.mpc.core"/>
+ <service>
+ <provide interface="org.eclipse.osgi.service.debug.DebugOptionsListener"/>
+ </service>
+ <implementation class="org.eclipse.epp.internal.mpc.core.MarketplaceClientCorePlugin$DebugOptionsInitializer"/>
+</scr:component> \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.http.client.factory.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.http.client.factory.xml
new file mode 100644
index 00000000..933ce783
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.http.client.factory.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0" name="org.eclipse.epp.mpc.core.http.client.factory">
+ <service>
+ <provide interface="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientFactory"/>
+ </service>
+ <reference cardinality="0..n" field="customizers" field-option="replace" interface="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientCustomizer" name="customizers" policy="static" policy-option="greedy"/>
+ <implementation class="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientFactory"/>
+</scr:component> \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.http.client.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.http.client.xml
new file mode 100644
index 00000000..304d506b
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.http.client.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0" name="org.eclipse.epp.mpc.core.http.client">
+ <service>
+ <provide interface="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientService"/>
+ </service>
+ <reference bind="bindClientFactory" interface="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientFactory" name="ClientFactory" policy="dynamic" policy-option="greedy" unbind="unbindClientFactory" updated="bindClientFactory"/>
+ <reference bind="bindProxyService" field="proxyService" interface="org.eclipse.core.net.proxy.IProxyService" name="ProxyService" policy="dynamic" unbind="unbindProxyService"/>
+ <implementation class="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientService"/>
+</scr:component> \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.servicehelper.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.servicehelper.xml
new file mode 100644
index 00000000..df38a1e4
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.servicehelper.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="activate" deactivate="deactivate" name="org.eclipse.epp.mpc.core.servicehelper">
+ <service>
+ <provide interface="org.eclipse.epp.mpc.core.service.ServiceHelper"/>
+ <provide interface="org.eclipse.epp.internal.mpc.core.ServiceHelperImpl"/>
+ </service>
+ <implementation class="org.eclipse.epp.internal.mpc.core.ServiceHelperImpl"/>
+</scr:component> \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.servicelocator.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.servicelocator.xml
new file mode 100644
index 00000000..4ea9d38a
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.servicelocator.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.core.servicelocator">
+ <service>
+ <provide interface="org.eclipse.epp.mpc.core.service.IMarketplaceServiceLocator"/>
+ </service>
+ <reference bind="bindHttpClient" cardinality="1..1" interface="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientService" name="HttpClient" policy="dynamic" unbind="unbindHttpClient"/>
+ <implementation class="org.eclipse.epp.internal.mpc.core.ServiceLocator"/>
+</scr:component> \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-transport-factory.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.transport.http.factory.xml
index bf0ff9e3..2c295748 100644
--- a/org.eclipse.epp.mpc.core/OSGI-INF/services/httpclient-transport-factory.xml
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.transport.http.factory.xml
@@ -1,20 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014, 2018 The Eclipse Foundation and others.
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Eclipse Public License v2.0
- which accompanies this distribution, and is available at
- https://www.eclipse.org/legal/epl-2.0/
-
- SPDX-License-Identifier: EPL-2.0
-
- Contributors:
- The Eclipse Foundation - initial API and implementation
- -->
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.core.transport.http.factory">
- <implementation class="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientTransportFactory"/>
<service>
<provide interface="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientTransportFactory"/>
+ <provide interface="org.eclipse.epp.mpc.core.service.ITransportFactory"/>
</service>
<reference bind="bindTransport" cardinality="1..1" interface="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientTransport" name="org.eclipse.epp.mpc.core.transport.http" policy="static" unbind="unbindTransport"/>
-</scr:component>
+ <implementation class="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientTransportFactory"/>
+</scr:component> \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.transport.http.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.transport.http.xml
new file mode 100644
index 00000000..b21c3d1d
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.transport.http.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.core.transport.http">
+ <service>
+ <provide interface="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientTransport"/>
+ <provide interface="org.eclipse.epp.mpc.core.service.ITransport"/>
+ </service>
+ <reference bind="bindHttpClientService" interface="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientService" name="HttpClientService"/>
+ <implementation class="org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientTransport"/>
+</scr:component> \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.transportfactory.legacy.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.transportfactory.legacy.xml
new file mode 100644
index 00000000..3cc48af0
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.transportfactory.legacy.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="activate" deactivate="deactivate" name="org.eclipse.epp.mpc.core.transportfactory.legacy">
+ <property name="org.eclipse.epp.mpc.core.service.transport.legacy" type="Boolean" value="true"/>
+ <property name="service.ranking" type="Integer" value="-2147483647"/>
+ <service>
+ <provide interface="org.eclipse.epp.mpc.core.service.ITransportFactory"/>
+ </service>
+ <implementation class="org.eclipse.epp.internal.mpc.core.util.TransportFactory$LegacyFactory"/>
+</scr:component> \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.unmarshaller.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.unmarshaller.xml
new file mode 100644
index 00000000..79f8e914
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/org.eclipse.epp.mpc.core.unmarshaller.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.core.unmarshaller">
+ <service>
+ <provide interface="org.eclipse.epp.mpc.core.service.IMarketplaceUnmarshaller"/>
+ </service>
+ <implementation class="org.eclipse.epp.internal.mpc.core.service.MarketplaceUnmarshaller"/>
+</scr:component> \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/service-locator.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/service-locator.xml
deleted file mode 100644
index 85127228..00000000
--- a/org.eclipse.epp.mpc.core/OSGI-INF/services/service-locator.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014, 2018 The Eclipse Foundation and others.
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Eclipse Public License v2.0
- which accompanies this distribution, and is available at
- https://www.eclipse.org/legal/epl-2.0/
-
- SPDX-License-Identifier: EPL-2.0
-
- Contributors:
- The Eclipse Foundation - initial API and implementation
- -->
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.core.servicelocator">
- <implementation class="org.eclipse.epp.internal.mpc.core.ServiceLocator"/>
- <service>
- <provide interface="org.eclipse.epp.mpc.core.service.IMarketplaceServiceLocator"/>
- </service>
-</scr:component>
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/unmarshaller.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/unmarshaller.xml
deleted file mode 100644
index d3f8a5e5..00000000
--- a/org.eclipse.epp.mpc.core/OSGI-INF/services/unmarshaller.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014, 2018 The Eclipse Foundation and others.
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Eclipse Public License v2.0
- which accompanies this distribution, and is available at
- https://www.eclipse.org/legal/epl-2.0/
-
- SPDX-License-Identifier: EPL-2.0
-
- Contributors:
- The Eclipse Foundation - initial API and implementation
- -->
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.core.unmarshaller">
- <implementation class="org.eclipse.epp.internal.mpc.core.service.MarketplaceUnmarshaller"/>
- <service>
- <provide interface="org.eclipse.epp.mpc.core.service.IMarketplaceUnmarshaller"/>
- </service>
-</scr:component>
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/MarketplaceClientCorePlugin.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/MarketplaceClientCorePlugin.java
index d51b2129..5c7f2ccc 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/MarketplaceClientCorePlugin.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/MarketplaceClientCorePlugin.java
@@ -13,25 +13,14 @@
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Hashtable;
-import java.util.List;
-
import org.eclipse.epp.internal.mpc.core.util.DebugTraceUtil;
-import org.eclipse.epp.internal.mpc.core.util.ProxyHelper;
-import org.eclipse.epp.internal.mpc.core.util.TransportFactory;
-import org.eclipse.epp.mpc.core.service.ITransportFactory;
+import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugOptionsListener;
import org.eclipse.osgi.service.debug.DebugTrace;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.annotations.Component;
public class MarketplaceClientCorePlugin implements BundleActivator {
@@ -53,106 +42,24 @@ public class MarketplaceClientCorePlugin implements BundleActivator {
private Bundle bundle;
- private List<ServiceRegistration<?>> serviceRegistrations;
-
- private ServiceHelperImpl serviceHelper;
-
@Override
public void start(BundleContext context) throws Exception {
bundle = context.getBundle();
instance = this;
- ProxyHelper.acquireProxyService();
- registerServices(context);
- serviceHelper = new ServiceHelperImpl();
- serviceHelper.startTracking(context);
-
- Hashtable<String, String> props = new Hashtable<>(2);
- props.put(org.eclipse.osgi.service.debug.DebugOptions.LISTENER_SYMBOLICNAME, MarketplaceClientCore.BUNDLE_ID);
- context.registerService(DebugOptionsListener.class.getName(), (DebugOptionsListener) options -> {
- DebugTrace debugTrace = null;
- boolean debug = options.getBooleanOption(MarketplaceClientCore.BUNDLE_ID + DEBUG_OPTION, false);
- boolean fakeClient = false;
- if (debug) {
- debugTrace = options.newDebugTrace(MarketplaceClientCore.BUNDLE_ID);
- fakeClient = options.getBooleanOption(MarketplaceClientCore.BUNDLE_ID + DEBUG_FAKE_CLIENT_OPTION,
- false);
- }
- DEBUG = debug;
- DEBUG_FAKE_CLIENT = fakeClient;
- MarketplaceClientCorePlugin.debugTrace = debugTrace;
- }, props);
}
@Override
public void stop(BundleContext context) throws Exception {
- serviceHelper.stopTracking(context);
- serviceHelper = null;
- unregisterServices();
- ProxyHelper.releaseProxyService();
debugTrace = null;
instance = null;
}
- private void registerServices(BundleContext context) throws InvalidSyntaxException {
- List<ServiceRegistration<?>> serviceRegistrations = new ArrayList<>();
- this.serviceRegistrations = serviceRegistrations;
-
- List<ITransportFactory> factories = TransportFactory.listAvailableFactories();//highest-prio factory comes first
- if (factories.isEmpty()) {
- return;
- }
-
- Collection<ServiceReference<ITransportFactory>> serviceReferences = context
- .getServiceReferences(ITransportFactory.class, null);
- int lowestPriority = Integer.MAX_VALUE;
- for (ServiceReference<ITransportFactory> serviceReference : serviceReferences) {
- Object legacyProperty = serviceReference.getProperty(TransportFactory.LEGACY_TRANSPORT_KEY);
- if (legacyProperty != null) {
- continue;
- }
- Integer ranking = (Integer) serviceReference.getProperty(Constants.SERVICE_RANKING);
- lowestPriority = Math.min(lowestPriority, ranking == null ? 0 : ranking.intValue());
- }
-
- int maxLegacyPriority, step;
- if (lowestPriority >= 0) {
- maxLegacyPriority = -100;
- step = 100;
- } else {
- int available = lowestPriority - Integer.MIN_VALUE;
- step = Math.min(100, available / factories.size());
- if (step == 0) {
- step = 1;
- maxLegacyPriority = Integer.MIN_VALUE + factories.size();
- } else {
- maxLegacyPriority = lowestPriority - step;
- }
- }
- int prio = maxLegacyPriority;//prio counts down from 0 in steps of 100
- for (ITransportFactory factory : factories) {
- Hashtable<String, Object> properties = new Hashtable<>();
- properties.put(Constants.SERVICE_RANKING, prio);
- properties.put(ComponentConstants.COMPONENT_NAME, "legacy:" + factory.getClass().getName());
- properties.put(TransportFactory.LEGACY_TRANSPORT_KEY, true);
- ServiceRegistration<ITransportFactory> registration = context.registerService(ITransportFactory.class,
- factory, properties);
- serviceRegistrations.add(registration);
- prio -= step;
- }
- }
-
- private void unregisterServices() {
- List<ServiceRegistration<?>> serviceRegistrations = this.serviceRegistrations;
- this.serviceRegistrations = null;
- if (serviceRegistrations != null) {
- for (ServiceRegistration<?> serviceRegistration : serviceRegistrations) {
- serviceRegistration.unregister();
- }
- }
- }
-
+ /**
+ * @deprecated Inject ServiceHelper as a service instead
+ */
+ @Deprecated
public ServiceHelperImpl getServiceHelper() {
- return serviceHelper;
+ return ServiceHelperImpl.getImplInstance();
}
public static MarketplaceClientCorePlugin getDefault() {
@@ -176,4 +83,25 @@ public class MarketplaceClientCorePlugin implements BundleActivator {
DebugTraceUtil.trace(trace, option, message, parameters);
}
}
+
+ @Component(name = "org.eclipse.epp.mpc.core.debug.options", property = {
+ "listener.symbolic.name=org.eclipse.epp.mpc.core" })
+ public static class DebugOptionsInitializer implements DebugOptionsListener {
+
+ @Override
+ public void optionsChanged(DebugOptions options) {
+ DebugTrace debugTrace = null;
+ boolean debug = options.getBooleanOption(MarketplaceClientCore.BUNDLE_ID + DEBUG_OPTION, false);
+ boolean fakeClient = false;
+ if (debug) {
+ debugTrace = options.newDebugTrace(MarketplaceClientCore.BUNDLE_ID);
+ fakeClient = options.getBooleanOption(MarketplaceClientCore.BUNDLE_ID + DEBUG_FAKE_CLIENT_OPTION,
+ false);
+ }
+ DEBUG = debug;
+ DEBUG_FAKE_CLIENT = fakeClient;
+ MarketplaceClientCorePlugin.debugTrace = debugTrace;
+ }
+
+ }
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceHelperImpl.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceHelperImpl.java
index e8a952c0..ca5716c0 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceHelperImpl.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceHelperImpl.java
@@ -12,7 +12,11 @@
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
import org.eclipse.epp.internal.mpc.core.util.ServiceUtil;
import org.eclipse.epp.internal.mpc.core.util.TransportFactory;
@@ -23,14 +27,25 @@ import org.eclipse.epp.mpc.core.service.IMarketplaceUnmarshaller;
import org.eclipse.epp.mpc.core.service.ITransportFactory;
import org.eclipse.epp.mpc.core.service.ServiceHelper;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
import org.osgi.util.tracker.ServiceTracker;
/**
* @author Carsten Reckord
*/
+@Component(name = "org.eclipse.epp.mpc.core.servicehelper", service = { ServiceHelper.class, ServiceHelperImpl.class })
public class ServiceHelperImpl extends ServiceHelper {
+ private static ServiceHelperImpl instance;
+
private ServiceTracker<IMarketplaceServiceLocator, IMarketplaceServiceLocator> locatorServiceTracker;
private ServiceTracker<ITransportFactory, ITransportFactory> transportFactoryTracker;
@@ -39,27 +54,45 @@ public class ServiceHelperImpl extends ServiceHelper {
private ServiceTracker<IMarketplaceUnmarshaller, IMarketplaceUnmarshaller> unmarshallerTracker;
- private BundleContext context;
+ private ComponentContext context;
+
+ private List<ServiceRegistration<?>> serviceRegistrations;
- void startTracking(final BundleContext context) {
+ @Activate
+ void activate(final ComponentContext context) throws InvalidSyntaxException {
this.context = context;
- locatorServiceTracker = new ServiceTracker<>(context,
+ BundleContext bundleContext = context.getBundleContext();
+
+ registerServices(bundleContext);
+
+ locatorServiceTracker = new ServiceTracker<>(bundleContext,
IMarketplaceServiceLocator.class, null);
locatorServiceTracker.open(true);
- transportFactoryTracker = new ServiceTracker<>(context,
+ transportFactoryTracker = new ServiceTracker<>(bundleContext,
ITransportFactory.class, null);
transportFactoryTracker.open(true);
- legacyTransportFactoryTracker = new TransportFactory.LegacyTransportFactoryTracker(context);
+ legacyTransportFactoryTracker = new TransportFactory.LegacyTransportFactoryTracker(bundleContext);
legacyTransportFactoryTracker.open(true);
- unmarshallerTracker = new ServiceTracker<>(context,
+ unmarshallerTracker = new ServiceTracker<>(bundleContext,
IMarketplaceUnmarshaller.class, null);
unmarshallerTracker.open(true);
+ synchronized (ServiceHelperImpl.class) {
+ if (instance == null) {
+ instance = this;
+ }
+ }
}
- void stopTracking(BundleContext context) {
+ @Deactivate
+ void deactivate(BundleContext context) {
+ synchronized (ServiceHelperImpl.class) {
+ if (instance == this) {
+ instance = null;
+ }
+ }
this.context = null;
if (locatorServiceTracker != null) {
locatorServiceTracker.close();
@@ -77,6 +110,65 @@ public class ServiceHelperImpl extends ServiceHelper {
unmarshallerTracker.close();
unmarshallerTracker = null;
}
+ unregisterServices();
+ }
+
+ private void registerServices(BundleContext context) throws InvalidSyntaxException {
+ List<ServiceRegistration<?>> serviceRegistrations = new ArrayList<>();
+ this.serviceRegistrations = serviceRegistrations;
+
+ List<ITransportFactory> factories = TransportFactory.listAvailableFactories();//highest-prio factory comes first
+ if (factories.isEmpty()) {
+ return;
+ }
+
+ Collection<ServiceReference<ITransportFactory>> serviceReferences = context
+ .getServiceReferences(ITransportFactory.class, null);
+ int lowestPriority = Integer.MAX_VALUE;
+ for (ServiceReference<ITransportFactory> serviceReference : serviceReferences) {
+ Object legacyProperty = serviceReference.getProperty(TransportFactory.LEGACY_TRANSPORT_KEY);
+ if (legacyProperty != null) {
+ continue;
+ }
+ Integer ranking = (Integer) serviceReference.getProperty(Constants.SERVICE_RANKING);
+ lowestPriority = Math.min(lowestPriority, ranking == null ? 0 : ranking.intValue());
+ }
+
+ int maxLegacyPriority, step;
+ if (lowestPriority >= 0) {
+ maxLegacyPriority = -100;
+ step = 100;
+ } else {
+ int available = lowestPriority - Integer.MIN_VALUE;
+ step = Math.min(100, available / factories.size());
+ if (step == 0) {
+ step = 1;
+ maxLegacyPriority = Integer.MIN_VALUE + factories.size();
+ } else {
+ maxLegacyPriority = lowestPriority - step;
+ }
+ }
+ int prio = maxLegacyPriority;//prio counts down from 0 in steps of 100
+ for (ITransportFactory factory : factories) {
+ Hashtable<String, Object> properties = new Hashtable<>();
+ properties.put(Constants.SERVICE_RANKING, prio);
+ properties.put(ComponentConstants.COMPONENT_NAME, "legacy:" + factory.getClass().getName());
+ properties.put(TransportFactory.LEGACY_TRANSPORT_KEY, true);
+ ServiceRegistration<ITransportFactory> registration = context.registerService(ITransportFactory.class,
+ factory, properties);
+ serviceRegistrations.add(registration);
+ prio -= step;
+ }
+ }
+
+ private void unregisterServices() {
+ List<ServiceRegistration<?>> serviceRegistrations = this.serviceRegistrations;
+ this.serviceRegistrations = null;
+ if (serviceRegistrations != null) {
+ for (ServiceRegistration<?> serviceRegistration : serviceRegistrations) {
+ serviceRegistration.unregister();
+ }
+ }
}
@Override
@@ -107,30 +199,60 @@ public class ServiceHelperImpl extends ServiceHelper {
public ServiceRegistration<IMarketplaceServiceLocator> registerMarketplaceServiceLocator(
IMarketplaceServiceLocator marketplaceServiceLocator) {
- return context.registerService(IMarketplaceServiceLocator.class, marketplaceServiceLocator,
- ServiceUtil.higherServiceRanking(locatorServiceTracker.getServiceReference(), null));
+ return context.getBundleContext()
+ .registerService(IMarketplaceServiceLocator.class, marketplaceServiceLocator,
+ ServiceUtil.higherServiceRanking(locatorServiceTracker.getServiceReference(), null));
}
public ServiceRegistration<IMarketplaceUnmarshaller> registerMarketplaceUnmarshaller(
IMarketplaceUnmarshaller unmarshaller) {
- return context.registerService(IMarketplaceUnmarshaller.class, unmarshaller,
- ServiceUtil.higherServiceRanking(unmarshallerTracker.getServiceReference(), null));
+ return context.getBundleContext()
+ .registerService(IMarketplaceUnmarshaller.class, unmarshaller,
+ ServiceUtil.higherServiceRanking(unmarshallerTracker.getServiceReference(), null));
}
public ServiceRegistration<ITransportFactory> registerTransportFactory(ITransportFactory transportFactory) {
- return context.registerService(ITransportFactory.class, transportFactory,
- ServiceUtil.higherServiceRanking(transportFactoryTracker.getServiceReference(), null));
+ return context.getBundleContext()
+ .registerService(ITransportFactory.class, transportFactory,
+ ServiceUtil.higherServiceRanking(transportFactoryTracker.getServiceReference(), null));
}
public ServiceRegistration<IMarketplaceService> registerMarketplaceService(String baseUrl,
IMarketplaceService marketplaceService) {
Dictionary<String, Object> properties = ServiceUtil.serviceRanking(Integer.MAX_VALUE, null);
properties.put(IMarketplaceService.BASE_URL, baseUrl);
- return context.registerService(IMarketplaceService.class, marketplaceService, properties);
+ return context.getBundleContext().registerService(IMarketplaceService.class, marketplaceService, properties);
}
public ServiceRegistration<ICatalogService> registerCatalogService(ICatalogService catalogService) {
- return context.registerService(ICatalogService.class, catalogService,
- ServiceUtil.serviceRanking(Integer.MAX_VALUE, null));
+ return context.getBundleContext()
+ .registerService(ICatalogService.class, catalogService,
+ ServiceUtil.serviceRanking(Integer.MAX_VALUE, null));
+ }
+
+ /**
+ * @noreference For test purposes only. This method is not intended to be referenced by clients.
+ */
+ public void setSuspended(boolean suspend) throws Exception {
+ String pid = (String) context.getProperties().get(Constants.SERVICE_PID);
+ if (suspend) {
+ context.disableComponent(pid);
+ unregisterServices();
+ } else {
+ context.enableComponent(pid);
+ //registerServices(context.getBundleContext());
+ }
+ }
+
+ public static ServiceHelperImpl getImplInstance() {
+ synchronized (ServiceHelperImpl.class) {
+ if (instance == null) {
+ ServiceHelperImpl registered = ServiceUtil.getService(ServiceHelperImpl.class, ServiceHelperImpl.class);
+ if (instance == null && registered != null) {
+ instance = registered;
+ }
+ }
+ return instance;
+ }
}
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceLocator.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceLocator.java
index 1cb1a4da..5347fe38 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceLocator.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceLocator.java
@@ -29,6 +29,7 @@ import org.eclipse.epp.internal.mpc.core.service.DefaultCatalogService;
import org.eclipse.epp.internal.mpc.core.service.DefaultMarketplaceService;
import org.eclipse.epp.internal.mpc.core.service.MarketplaceStorageService;
import org.eclipse.epp.internal.mpc.core.service.UserFavoritesService;
+import org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientService;
import org.eclipse.epp.internal.mpc.core.util.ServiceUtil;
import org.eclipse.epp.internal.mpc.core.util.URLUtil;
import org.eclipse.epp.mpc.core.service.ICatalogService;
@@ -42,6 +43,10 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
@@ -51,9 +56,10 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
* @author David Green
* @author Carsten Reckord
*/
+@Component(name = "org.eclipse.epp.mpc.core.servicelocator", service = IMarketplaceServiceLocator.class)
public class ServiceLocator implements IMarketplaceServiceLocator {
- public static final String STORAGE_SERVICE_BINDING_ID = "bind.storageService"; //$NON-NLS-1$
+ private static final String STORAGE_SERVICE_BINDING_ID = "bind.storageService"; //$NON-NLS-1$
private abstract class DynamicBindingOperation<T, B> implements ServiceReferenceOperation<T> {
@@ -113,11 +119,69 @@ public class ServiceLocator implements IMarketplaceServiceLocator {
private final List<ServiceRegistration<?>> dynamicServiceRegistrations = new ArrayList<>();
+ private HttpClientService httpClient;
+
public ServiceLocator() {
defaultMarketplaceUrl = DefaultMarketplaceService.DEFAULT_SERVICE_URL;
defaultCatalogUrl = DefaultCatalogService.DEFAULT_CATALOG_SERVICE_URL;
}
+ public HttpClientService getHttpClient() {
+ return httpClient;
+ }
+
+ public void setHttpClient(HttpClientService httpClient) {
+ HttpClientService oldClient = this.httpClient;
+ this.httpClient = httpClient;
+ if (oldClient != httpClient) {
+ updateHttpClient(httpClient);
+ }
+ }
+
+ @Reference(unbind = "unbindHttpClient", cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC)
+ public void bindHttpClient(HttpClientService httpClient) {
+ setHttpClient(httpClient);
+ }
+
+ public void unbindHttpClient(HttpClientService httpClient) {
+ if (this.httpClient == httpClient) {
+ setHttpClient(null);
+ }
+ }
+
+ private void updateHttpClient(HttpClientService httpClient) {
+ applyServiceReferenceOperation(favoritesServiceTracker, new ServiceReferenceOperation<IUserFavoritesService>() {
+
+ @Override
+ public void apply(ServiceReference<IUserFavoritesService> reference) {
+ ServiceRegistration<IUserFavoritesService> registration = getDynamicServiceInstance(reference);
+ if (registration != null) {
+ IUserFavoritesService service = ServiceUtil.getService(registration);
+ if (service instanceof UserFavoritesService) {
+ if (httpClient == null) {
+ ((UserFavoritesService) service).unbindHttpClient(httpClient);
+ } else {
+ ((UserFavoritesService) service).bindHttpClient(httpClient);
+ }
+ }
+ }
+ }
+ });
+ applyServiceReferenceOperation(marketplaceServiceTracker, new ServiceReferenceOperation<IMarketplaceService>() {
+
+ @Override
+ public void apply(ServiceReference<IMarketplaceService> reference) {
+ ServiceRegistration<IMarketplaceService> registration = getDynamicServiceInstance(reference);
+ if (registration != null) {
+ IMarketplaceService service = ServiceUtil.getService(registration);
+ if (service instanceof DefaultMarketplaceService) {
+ ((DefaultMarketplaceService) service).setHttpClient(httpClient);
+ }
+ }
+ }
+ });
+ }
+
/**
* @deprecated use {@link #getDefaultMarketplaceService()} or {@link #getMarketplaceService(String)} instead
*/
@@ -194,6 +258,7 @@ public class ServiceLocator implements IMarketplaceServiceLocator {
defaultService.setRequestMetaParameters(requestMetaParameters);
IUserFavoritesService favoritesService = getFavoritesService(baseUrl);
defaultService.setUserFavoritesService(favoritesService);//FIXME this should be a service reference!
+ defaultService.setHttpClient(httpClient);
service = new CachingMarketplaceService(defaultService);
return service;
}
@@ -229,6 +294,7 @@ public class ServiceLocator implements IMarketplaceServiceLocator {
}
UserFavoritesService favoritesService = new UserFavoritesService();
favoritesService.bindStorageService(storageService);
+ favoritesService.bindHttpClient(httpClient);
registerService(marketplaceBaseUrl, IUserFavoritesService.class, favoritesService);
return favoritesService;
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java
index 083da73d..ab3dcd3c 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java
@@ -20,6 +20,7 @@ import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
@@ -32,9 +33,9 @@ import java.util.Set;
import java.util.stream.Collectors;
import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -52,7 +53,8 @@ import org.eclipse.epp.internal.mpc.core.model.NodeListing;
import org.eclipse.epp.internal.mpc.core.model.Search;
import org.eclipse.epp.internal.mpc.core.model.SearchResult;
import org.eclipse.epp.internal.mpc.core.service.AbstractDataStorageService.NotAuthorizedException;
-import org.eclipse.epp.internal.mpc.core.util.HttpUtil;
+import org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientService;
+import org.eclipse.epp.internal.mpc.core.transport.httpclient.RequestTemplate;
import org.eclipse.epp.internal.mpc.core.util.ServiceUtil;
import org.eclipse.epp.internal.mpc.core.util.URLUtil;
import org.eclipse.epp.mpc.core.model.ICategory;
@@ -118,6 +120,8 @@ MarketplaceService {
public static final String API_FREETAGGING_URI = "category/free-tagging/"; //$NON-NLS-1$
+ private static final String API_ERROR_REPORT_URI = "install/error/report"; //$NON-NLS-1$
+
public static final String DEFAULT_SERVICE_LOCATION = System
.getProperty(IMarketplaceServiceLocator.DEFAULT_MARKETPLACE_PROPERTY_NAME, "http://marketplace.eclipse.org"); //$NON-NLS-1$
@@ -171,6 +175,8 @@ MarketplaceService {
private IUserFavoritesService userFavoritesService;
+ private HttpClientService httpClient;
+
public DefaultMarketplaceService(URL baseUrl) {
this.baseUrl = baseUrl == null ? DEFAULT_SERVICE_URL : baseUrl;
}
@@ -775,19 +781,6 @@ MarketplaceService {
@Override
public void reportInstallError(IStatus result, Set<? extends INode> nodes, Set<String> iuIdsAndVersions,
String resolutionDetails, IProgressMonitor monitor) throws CoreException {
- HttpClient client;
- URL location;
- HttpPost method;
- try {
- location = new URL(baseUrl, "install/error/report"); //$NON-NLS-1$
- String target = location.toURI().toString();
- client = HttpUtil.createHttpClient(target);
- method = new HttpPost(target);
- } catch (URISyntaxException e) {
- throw new IllegalStateException(e);
- } catch (MalformedURLException e) {
- throw new IllegalStateException(e);
- }
try {
List<NameValuePair> parameters = new ArrayList<>();
@@ -811,15 +804,29 @@ MarketplaceService {
parameters.add(new BasicNameValuePair("detailedMessage", resolutionDetails)); //$NON-NLS-1$
if (!parameters.isEmpty()) {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8);
- method.setEntity(entity);
- client.execute(method);
+ new RequestTemplate<Void>() {
+
+ @Override
+ protected HttpUriRequest createRequest(URI uri) {
+ return RequestBuilder.post(uri.resolve(API_ERROR_REPORT_URI)).setEntity(entity).build();
+ }
+
+ @Override
+ protected Void handleResponseStream(InputStream content, Charset charset) throws IOException {
+ // ignore
+ return null;
+ }
+
+ }.execute(httpClient, baseUrl.toURI());
}
+ } catch (URISyntaxException e) {
+ throw new IllegalStateException(e);
+ } catch (MalformedURLException e) {
+ throw new IllegalStateException(e);
} catch (IOException e) {
String message = NLS.bind(Messages.DefaultMarketplaceService_cannotCompleteRequest_reason,
- location.toString(), e.getMessage());
+ baseUrl.toString() + API_ERROR_REPORT_URI, e.getMessage());
throw new CoreException(createErrorStatus(message, e));
- } finally {
- client.getConnectionManager().shutdown();
}
}
@@ -854,4 +861,12 @@ MarketplaceService {
public void setUserFavoritesService(IUserFavoritesService userFavoritesService) {
this.userFavoritesService = userFavoritesService;
}
+
+ public void setHttpClient(HttpClientService httpClient) {
+ this.httpClient = httpClient;
+ }
+
+ public HttpClientService getHttpClient() {
+ return httpClient;
+ }
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceUnmarshaller.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceUnmarshaller.java
index 0abcaf52..37f4d8a2 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceUnmarshaller.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceUnmarshaller.java
@@ -37,6 +37,7 @@ import org.eclipse.epp.internal.mpc.core.service.xml.Unmarshaller;
import org.eclipse.epp.mpc.core.service.IMarketplaceUnmarshaller;
import org.eclipse.epp.mpc.core.service.UnmarshalException;
import org.eclipse.osgi.util.NLS;
+import org.osgi.service.component.annotations.Component;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
@@ -44,6 +45,7 @@ import org.xml.sax.XMLReader;
/**
* @author Carsten Reckord
*/
+@Component(name = "org.eclipse.epp.mpc.core.unmarshaller")
public class MarketplaceUnmarshaller implements IMarketplaceUnmarshaller {
@Override
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/UserFavoritesService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/UserFavoritesService.java
index 5bc2b506..b05ac7da 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/UserFavoritesService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/UserFavoritesService.java
@@ -37,7 +37,8 @@ import java.util.regex.Pattern;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
-import org.apache.http.client.fluent.Request;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.methods.RequestBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
@@ -45,6 +46,7 @@ import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
import org.eclipse.epp.internal.mpc.core.model.FavoriteList;
+import org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientService;
import org.eclipse.epp.internal.mpc.core.transport.httpclient.RequestTemplate;
import org.eclipse.epp.internal.mpc.core.util.URLUtil;
import org.eclipse.epp.mpc.core.model.IFavoriteList;
@@ -138,6 +140,8 @@ public class UserFavoritesService extends AbstractDataStorageService implements
private final Set<String> favorites = new HashSet<>();
+ private HttpClientService httpClient;
+
protected IBlob getFavoritesBlob() {
return getStorageService().getBlob(KEY);
}
@@ -232,7 +236,7 @@ public class UserFavoritesService extends AbstractDataStorageService implements
return favoritesByUserId;
}
- }.execute(randomFavoritesUri);
+ }.execute(httpClient, randomFavoritesUri);
}
private static String getAttribute(Pattern attributePattern, String attributeName, String entryBody) {
@@ -518,7 +522,7 @@ public class UserFavoritesService extends AbstractDataStorageService implements
return null;
}
- }.execute(uri);
+ }.execute(httpClient, uri);
} catch (FileNotFoundException e) {
return new ArrayList<>();
}
@@ -617,10 +621,10 @@ public class UserFavoritesService extends AbstractDataStorageService implements
}
@Override
- protected Request configureRequest(Request request, URI uri) {
- return super.configureRequest(request, uri).setHeader(HttpHeaders.USER_AGENT, Session.USER_AGENT_ID)
- .addHeader(HttpHeaders.CONTENT_TYPE, Session.APPLICATION_JSON) //
- .addHeader(HttpHeaders.ACCEPT, Session.APPLICATION_JSON);
+ protected HttpUriRequest configureRequest(HttpClientService client, HttpUriRequest request) {
+ HttpUriRequest configuredRequest = super.configureRequest(client, request);
+ configuredRequest.setHeader(HttpHeaders.USER_AGENT, Session.USER_AGENT_ID);
+ return configuredRequest;
}
@Override
@@ -675,8 +679,30 @@ public class UserFavoritesService extends AbstractDataStorageService implements
protected abstract T parseListElement(String listElement);
@Override
- protected Request createRequest(URI uri) {
- return Request.Get(uri);
+ protected HttpUriRequest createRequest(URI uri) {
+ return RequestBuilder.get(uri)
+ .addHeader(HttpHeaders.CONTENT_TYPE, Session.APPLICATION_JSON) //
+ .addHeader(HttpHeaders.ACCEPT, Session.APPLICATION_JSON)
+ .build();
}
}
+
+ public void setHttpClient(HttpClientService httpClient) {
+ this.httpClient = httpClient;
+ }
+
+ public HttpClientService getHttpClient() {
+ return httpClient;
+ }
+
+ public void bindHttpClient(HttpClientService httpClient) {
+ setHttpClient(httpClient);
+ }
+
+ public void unbindHttpClient(HttpClientService httpClient) {
+ if (this.httpClient == httpClient) {
+ setHttpClient(null);
+ }
+ }
+
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientFactory.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientFactory.java
index d8728626..d779f174 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientFactory.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientFactory.java
@@ -1,231 +1,230 @@
-/*******************************************************************************
+/*******************************************************************************
* Copyright (c) 2010, 2018 The Eclipse Foundation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * The Eclipse Foundation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.epp.internal.mpc.core.transport.httpclient;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.client.CookieStore;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.fluent.Executor;
-import org.apache.http.config.SocketConfig;
-import org.apache.http.impl.client.BasicCookieStore;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.client.ProxyAuthenticationStrategy;
-import org.apache.http.impl.client.TargetAuthenticationStrategy;
-import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
-import org.eclipse.userstorage.internal.StorageProperties;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-
-class HttpClientFactory {
-
- private CredentialsProvider credentialsProvider;
-
- private CookieStore cookieStore;
-
- private HttpClient client;
-
- private Executor executor;
-
- public HttpClient build() {
- HttpClientBuilder clientBuilder = createClientBuilder();
-
- if (cookieStore == null) {
- cookieStore = new BasicCookieStore();
- }
-
- if (credentialsProvider == null) {
- credentialsProvider = createCredentialsProvider(clientBuilder);
- }
-
- clientBuilder.setDefaultCredentialsProvider(credentialsProvider);
- clientBuilder.setDefaultCookieStore(cookieStore);
- client = clientBuilder.build();
-
- executor = Executor.newInstance(client).use(cookieStore).use(credentialsProvider);
-
- return client;
- }
-
- private static CredentialsProvider createCredentialsProvider(HttpClientBuilder clientBuilder) {
- //TODO we should handle configured proxy passwords and dialogs to prompt for unknown credentials on our own...
- CredentialsProvider credentialsProvider = new SystemCredentialsProvider();
- credentialsProvider = customizeCredentialsProvider(credentialsProvider);
-
- final CacheCredentialsProvider cacheProvider = new CacheCredentialsProvider();
- credentialsProvider = new ChainedCredentialsProvider(cacheProvider, credentialsProvider);
- credentialsProvider = new SynchronizedCredentialsProvider(credentialsProvider);
-
- clientBuilder.addInterceptorFirst((HttpRequestInterceptor) (request, context) -> context
- .setAttribute(CacheCredentialsAuthenticationStrategy.CREDENTIALS_CACHE_ATTRIBUTE, cacheProvider));
-
- return credentialsProvider;
- }
-
- private static HttpClientBuilder createClientBuilder() {
- HttpClientBuilder builder = HttpClientBuilder.create();
- builder = customizeBuilder(builder);
-
- builder.setMaxConnPerRoute(100).setMaxConnTotal(200);
- setClientTimeouts(builder);
-
- builder.setTargetAuthenticationStrategy(
- new CacheCredentialsAuthenticationStrategy.Target(TargetAuthenticationStrategy.INSTANCE));
- builder.setProxyAuthenticationStrategy(
- new CacheCredentialsAuthenticationStrategy.Proxy(ProxyAuthenticationStrategy.INSTANCE));
-
- builder.setUserAgent(HttpClientTransport.USER_AGENT);
-
- return builder;
- }
-
- private static void setClientTimeouts(HttpClientBuilder builder) {
- @SuppressWarnings("restriction")
- int connectTimeoutUssDefault = StorageProperties
- .getProperty(StorageProperties.CONNECT_TIMEOUT, HttpClientTransport.DEFAULT_CONNECT_TIMEOUT);
- @SuppressWarnings("restriction")
- int readTimeoutUssDefault = StorageProperties.getProperty(StorageProperties.SOCKET_TIMEOUT,
- HttpClientTransport.DEFAULT_READ_TIMEOUT);
-
- int connectTimeout = getTimeoutValue(HttpClientTransport.CONNECT_TIMEOUT_PROPERTY, connectTimeoutUssDefault);
- int readTimeout = getTimeoutValue(HttpClientTransport.READ_TIMEOUT_PROPERTY, readTimeoutUssDefault);
-
- int connectionRequestTimeout = getTimeoutValue(HttpClientTransport.CONNECTION_REQUEST_TIMEOUT_PROPERTY,
- HttpClientTransport.DEFAULT_CONNECTION_REQUEST_TIMEOUT);
-
- SocketConfig defaultSocketConfig = SocketConfig.copy(SocketConfig.DEFAULT)
- .setSoTimeout(readTimeout)
- .setTcpNoDelay(true)//Disable Nagle - see https://en.wikipedia.org/wiki/Nagle%27s_algorithm#Negative_effect_on_larger_writes
- //.setSoLinger(0)
- //TODO is it safe to set this to 0? This will forcefully terminate sockets on close instead of waiting for graceful close
- //See http://docs.oracle.com/javase/6/docs/api/java/net/SocketOptions.html?is-external=true#SO_LINGER
- //and https://issues.apache.org/jira/browse/HTTPCLIENT-1497
- .build();
- RequestConfig defaultRequestConfig = RequestConfig.copy(RequestConfig.DEFAULT)
- .setSocketTimeout(readTimeout)
- .setConnectTimeout(connectTimeout)
- .setConnectionRequestTimeout(connectionRequestTimeout)
- .build();
- builder.setDefaultSocketConfig(defaultSocketConfig);
- builder.setDefaultRequestConfig(defaultRequestConfig);
- }
-
- private static int getTimeoutValue(String property, int defaultValue) {
- String propertyValue = FrameworkUtil.getBundle(HttpClientTransport.class)
- .getBundleContext()
- .getProperty(property);
- if (propertyValue == null || "".equals(propertyValue)) { //$NON-NLS-1$
- return defaultValue;
- }
- try {
- return Integer.parseInt(propertyValue);
- } catch (NumberFormatException ex) {
- //TODO log
- return defaultValue;
- }
- }
-
- private static HttpClientBuilder customizeBuilder(HttpClientBuilder builder) {
- BundleContext context = getBundleContext();
- Collection<ServiceReference<HttpClientCustomizer>> serviceReferences = getClientBuilderCustomizers(context);
- HttpClientBuilder customBuilder = builder;
- for (ServiceReference<HttpClientCustomizer> reference : serviceReferences) {
- try {
- HttpClientCustomizer service = context.getService(reference);
- customBuilder = customizeBuilder(service, customBuilder);
- } finally {
- context.ungetService(reference);
- }
- }
- return customBuilder;
- }
-
- private static HttpClientBuilder customizeBuilder(HttpClientCustomizer service, HttpClientBuilder builder) {
- if (service == null) {
- return builder;
- }
- HttpClientBuilder customBuilder = service.customizeBuilder(builder);
- return customBuilder == null ? builder : customBuilder;
- }
-
- private static CredentialsProvider customizeCredentialsProvider(CredentialsProvider credentialsProvider) {
- BundleContext context = getBundleContext();
- Collection<ServiceReference<HttpClientCustomizer>> serviceReferences = getClientBuilderCustomizers(context);
- CredentialsProvider customizedCredentialsProvider = credentialsProvider;
- for (ServiceReference<HttpClientCustomizer> reference : serviceReferences) {
- try {
- HttpClientCustomizer service = context.getService(reference);
- customizedCredentialsProvider = customizeCredentialsProvider(service, customizedCredentialsProvider);
- } finally {
- context.ungetService(reference);
- }
- }
- return customizedCredentialsProvider;
- }
-
- private static CredentialsProvider customizeCredentialsProvider(HttpClientCustomizer service,
- CredentialsProvider credentialsProvider) {
- if (service == null) {
- return credentialsProvider;
- }
- CredentialsProvider customCredentialsProvider = service.customizeCredentialsProvider(credentialsProvider);
- return customCredentialsProvider == null ? credentialsProvider : customCredentialsProvider;
- }
-
- private static BundleContext getBundleContext() {
- return FrameworkUtil.getBundle(HttpClientTransport.class).getBundleContext();
- }
-
- private static Collection<ServiceReference<HttpClientCustomizer>> getClientBuilderCustomizers(
- BundleContext context) {
- Collection<ServiceReference<HttpClientCustomizer>> serviceReferences;
- try {
- serviceReferences = context.getServiceReferences(HttpClientCustomizer.class,
- /*TransportFactory.computeDisabledTransportsFilter()*/null);
- } catch (InvalidSyntaxException e) {
- MarketplaceClientCore.error(e);
- serviceReferences = Collections.emptySet();
- }
- return serviceReferences;
- }
-
- public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
- this.credentialsProvider = credentialsProvider;
- }
-
- public CredentialsProvider getCredentialsProvider() {
- return credentialsProvider;
- }
-
- public void setCookieStore(CookieStore cookieStore) {
- this.cookieStore = cookieStore;
- }
-
- public CookieStore getCookieStore() {
- return cookieStore;
- }
-
- public Executor getExecutor() {
- return executor;
- }
-
- public HttpClient getClient() {
- return client;
- }
-}
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.epp.internal.mpc.core.transport.httpclient;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.config.SocketConfig;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.ProxyAuthenticationStrategy;
+import org.apache.http.impl.client.TargetAuthenticationStrategy;
+import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
+import org.eclipse.userstorage.internal.StorageProperties;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.FieldOption;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+
+@Component(name = "org.eclipse.epp.mpc.core.http.client.factory", service = { HttpClientFactory.class })
+public class HttpClientFactory {
+
+ @Reference(cardinality = ReferenceCardinality.MULTIPLE, policyOption = ReferencePolicyOption.GREEDY, policy = ReferencePolicy.STATIC, fieldOption = FieldOption.REPLACE)
+ private List<HttpClientCustomizer> customizers;
+
+ public List<HttpClientCustomizer> getCustomizers() {
+ return customizers;
+ }
+
+ public void setCustomizers(List<HttpClientCustomizer> customizers) {
+ this.customizers = customizers;
+ }
+
+ public HttpServiceContext build() {
+ return build(null);
+ }
+
+ public HttpServiceContext build(HttpServiceContext oldContext) {
+ HttpClientBuilder clientBuilder = builder();
+
+ CookieStore cookieStore = oldContext == null ? null : oldContext.getCookieStore();
+ if (cookieStore == null) {
+ cookieStore = createCookieStore();
+ }
+
+ CredentialsProvider cacheProvider = oldContext == null ? null
+ : oldContext.getCredentialsCacheProvider();
+ if (cacheProvider == null) {
+ cacheProvider = createCredentialsCacheProvider();
+ }
+ CredentialsProvider initialCredentialsProvider = oldContext == null ? null
+ : oldContext.getInitialCredentialsProvider();
+ if (initialCredentialsProvider == null) {
+ initialCredentialsProvider = createCredentialsProvider();
+ }
+ CredentialsProvider credentialsProvider = initialCredentialsProvider;
+ if (credentialsProvider != null) {
+ credentialsProvider = customizeCredentialsProvider(clientBuilder, credentialsProvider, cacheProvider);
+ }
+
+ clientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+ clientBuilder.setDefaultCookieStore(cookieStore);
+
+ clientBuilder = customizeBuilder(clientBuilder);
+
+ return new HttpServiceContext(clientBuilder.build(), cookieStore, credentialsProvider,
+ initialCredentialsProvider, cacheProvider);
+ }
+
+ protected CredentialsProvider createCredentialsProvider() {
+ return new SystemCredentialsProvider();
+ }
+
+ protected CredentialsProvider createCredentialsCacheProvider() {
+ return new CacheCredentialsProvider();
+ }
+
+ protected CookieStore createCookieStore() {
+ return new BasicCookieStore();
+ }
+
+ private CredentialsProvider customizeCredentialsProvider(HttpClientBuilder clientBuilder,
+ CredentialsProvider credentialsProvider, CredentialsProvider cacheProvider) {
+ //TODO we should handle configured proxy passwords and dialogs to prompt for unknown credentials on our own...
+ credentialsProvider = customizeCredentialsProvider(credentialsProvider);
+
+ if (cacheProvider != null) {
+ credentialsProvider = new ChainedCredentialsProvider(cacheProvider, credentialsProvider);
+
+ clientBuilder.addInterceptorFirst((HttpRequestInterceptor) (request, context) -> context
+ .setAttribute(CacheCredentialsAuthenticationStrategy.CREDENTIALS_CACHE_ATTRIBUTE, cacheProvider));
+ }
+ credentialsProvider = new SynchronizedCredentialsProvider(credentialsProvider);
+
+ return credentialsProvider;
+ }
+
+ protected HttpClientBuilder builder() {
+ HttpClientBuilder builder = HttpClientBuilder.create();
+
+ builder.setMaxConnPerRoute(100).setMaxConnTotal(200);
+ setClientDefaultTimeouts(builder);
+
+ builder.setTargetAuthenticationStrategy(
+ new CacheCredentialsAuthenticationStrategy.Target(TargetAuthenticationStrategy.INSTANCE));
+ builder.setProxyAuthenticationStrategy(
+ new CacheCredentialsAuthenticationStrategy.Proxy(ProxyAuthenticationStrategy.INSTANCE));
+
+ builder.setUserAgent(HttpClientTransport.USER_AGENT);
+
+ return builder;
+ }
+
+ private static void setClientDefaultTimeouts(HttpClientBuilder builder) {
+ @SuppressWarnings("restriction")
+ int connectTimeoutUssDefault = StorageProperties.getProperty(StorageProperties.CONNECT_TIMEOUT,
+ HttpClientTransport.DEFAULT_CONNECT_TIMEOUT);
+ @SuppressWarnings("restriction")
+ int readTimeoutUssDefault = StorageProperties.getProperty(StorageProperties.SOCKET_TIMEOUT,
+ HttpClientTransport.DEFAULT_READ_TIMEOUT);
+
+ int connectTimeout = getTimeoutValue(HttpClientTransport.CONNECT_TIMEOUT_PROPERTY, connectTimeoutUssDefault);
+ int readTimeout = getTimeoutValue(HttpClientTransport.READ_TIMEOUT_PROPERTY, readTimeoutUssDefault);
+
+ int connectionRequestTimeout = getTimeoutValue(HttpClientTransport.CONNECTION_REQUEST_TIMEOUT_PROPERTY,
+ HttpClientTransport.DEFAULT_CONNECTION_REQUEST_TIMEOUT);
+
+ SocketConfig defaultSocketConfig = SocketConfig.copy(SocketConfig.DEFAULT)
+ .setSoTimeout(readTimeout)
+ .setTcpNoDelay(true)//Disable Nagle - see https://en.wikipedia.org/wiki/Nagle%27s_algorithm#Negative_effect_on_larger_writes
+ //.setSoLinger(0)
+ //TODO is it safe to set this to 0? This will forcefully terminate sockets on close instead of waiting for graceful close
+ //See http://docs.oracle.com/javase/6/docs/api/java/net/SocketOptions.html?is-external=true#SO_LINGER
+ //and https://issues.apache.org/jira/browse/HTTPCLIENT-1497
+ .build();
+ RequestConfig defaultRequestConfig = RequestConfig.copy(RequestConfig.DEFAULT)
+ .setSocketTimeout(readTimeout)
+ .setConnectTimeout(connectTimeout)
+ .setConnectionRequestTimeout(connectionRequestTimeout)
+ .build();
+ builder.setDefaultSocketConfig(defaultSocketConfig);
+ builder.setDefaultRequestConfig(defaultRequestConfig);
+ }
+
+ private static int getTimeoutValue(String property, int defaultValue) {
+ String propertyValue = FrameworkUtil.getBundle(HttpClientTransport.class)
+ .getBundleContext()
+ .getProperty(property);
+ if (propertyValue == null || "".equals(propertyValue)) { //$NON-NLS-1$
+ return defaultValue;
+ }
+ try {
+ return Integer.parseInt(propertyValue);
+ } catch (NumberFormatException ex) {
+ //TODO log
+ return defaultValue;
+ }
+ }
+
+ protected HttpClientBuilder customizeBuilder(HttpClientBuilder builder) {
+ HttpClientBuilder customBuilder = builder;
+ for (HttpClientCustomizer customizer : this.customizers) {
+ customBuilder = customizeBuilder(customizer, customBuilder);
+ }
+ return customBuilder;
+ }
+
+ private static HttpClientBuilder customizeBuilder(HttpClientCustomizer customizer, HttpClientBuilder builder) {
+ if (customizer == null) {
+ return builder;
+ }
+ HttpClientBuilder customBuilder = customizer.customizeBuilder(builder);
+ return customBuilder == null ? builder : customBuilder;
+ }
+
+ private CredentialsProvider customizeCredentialsProvider(CredentialsProvider credentialsProvider) {
+ CredentialsProvider customizedCredentialsProvider = credentialsProvider;
+ for (HttpClientCustomizer customizer : this.customizers) {
+ customizedCredentialsProvider = customizeCredentialsProvider(customizer, customizedCredentialsProvider);
+ }
+ return customizedCredentialsProvider;
+ }
+
+ private static CredentialsProvider customizeCredentialsProvider(HttpClientCustomizer customizer,
+ CredentialsProvider credentialsProvider) {
+ if (customizer == null) {
+ return credentialsProvider;
+ }
+ CredentialsProvider customCredentialsProvider = customizer.customizeCredentialsProvider(credentialsProvider);
+ return customCredentialsProvider == null ? credentialsProvider : customCredentialsProvider;
+ }
+
+ private static BundleContext getBundleContext() {
+ return FrameworkUtil.getBundle(HttpClientTransport.class).getBundleContext();
+ }
+
+ private static Collection<ServiceReference<HttpClientCustomizer>> getClientBuilderCustomizers(
+ BundleContext context) {
+ Collection<ServiceReference<HttpClientCustomizer>> serviceReferences;
+ try {
+ serviceReferences = context.getServiceReferences(HttpClientCustomizer.class,
+ /*TransportFactory.computeDisabledTransportsFilter()*/null);
+ } catch (InvalidSyntaxException e) {
+ MarketplaceClientCore.error(e);
+ serviceReferences = Collections.emptySet();
+ }
+ return serviceReferences;
+ }
+}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientService.java
new file mode 100644
index 00000000..46af4d40
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientService.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2018 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.epp.internal.mpc.core.transport.httpclient;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.NTCredentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.Configurable;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.methods.RequestBuilder;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.protocol.HttpContext;
+import org.eclipse.core.net.proxy.IProxyData;
+import org.eclipse.core.net.proxy.IProxyService;
+import org.eclipse.epp.internal.mpc.core.util.ProxyHelper;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+
+@Component(name = "org.eclipse.epp.mpc.core.http.client", service = { HttpClientService.class })
+public class HttpClientService {
+
+ private HttpClient client;
+
+ private HttpServiceContext context;
+
+ private IProxyService proxyService;
+
+ @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, updated = "bindClientFactory", unbind = "unbindClientFactory")
+ void bindClientFactory(HttpClientFactory factory) {
+ context = factory.build(context);
+ client = context.getClient();
+ }
+
+ void unbindClientFactory(HttpClientFactory factory) {
+ //do nothing
+ }
+
+ @Reference(field = "proxyService", unbind = "unbindProxyService", policy = ReferencePolicy.DYNAMIC)
+ void bindProxyService(IProxyService proxyService) {
+ this.proxyService = proxyService;
+ }
+
+ void unbindProxyService(IProxyService proxyService) {
+ if (this.proxyService == proxyService) {
+ this.proxyService = null;
+ }
+ }
+
+ public HttpResponse execute(HttpUriRequest request) throws ClientProtocolException, IOException {
+ return execute(request, null);
+ }
+
+ public HttpResponse execute(HttpUriRequest request, HttpContext context)
+ throws ClientProtocolException, IOException {
+ HttpClientContext internalContext = context == null ? new HttpClientContext()
+ : HttpClientContext.adapt(context);
+ HttpUriRequest configuredRequest = configureRequestExecution(request, internalContext);
+ return client.execute(configuredRequest, internalContext);
+ }
+
+ private HttpUriRequest configureRequestExecution(HttpUriRequest request, HttpClientContext context)
+ throws IOException {
+ final RequestConfig.Builder builder;
+ RequestConfig requestConfig = context.getRequestConfig();
+
+ if (requestConfig != null) {
+ builder = RequestConfig.copy(requestConfig);
+ } else if (request instanceof Configurable && ((Configurable) request).getConfig() != null) {
+ builder = RequestConfig.copy(((Configurable) request).getConfig());
+ } else if (client instanceof Configurable && ((Configurable) client).getConfig() != null) {
+ builder = RequestConfig.copy(((Configurable) client).getConfig());
+ } else {
+ builder = RequestConfig.custom();
+ }
+
+ configureRequestExecution(request, context, builder);
+
+ RequestConfig config = builder.build();
+ if (request instanceof HttpRequestBase) {
+ ((HttpRequestBase) request).setConfig(config);
+ return request;
+ } else {
+ return RequestBuilder.copy(request).setConfig(config).build();
+ }
+ }
+
+ protected void configureRequestExecution(HttpUriRequest request, HttpClientContext context,
+ RequestConfig.Builder builder) throws IOException {
+ configureProxy(request.getURI(), context, builder);
+ }
+
+ private static HttpUriRequest setConfig(HttpUriRequest request, RequestConfig config) {
+ if (request instanceof HttpRequestBase) {
+ ((HttpRequestBase) request).setConfig(config);
+ } else {
+ request = RequestBuilder.copy(request).setConfig(config).build();
+ }
+ return request;
+ }
+
+ public HttpUriRequest configureRequest(HttpUriRequest request) {
+ if (client instanceof Configurable && ((Configurable) client).getConfig() != null) {
+ return setConfig(request, ((Configurable) client).getConfig());
+ }
+ return request;
+ }
+
+ public HttpResponse configureAndExecute(HttpUriRequest request) throws ClientProtocolException, IOException {
+ return configureAndExecute(request, null);
+ }
+
+ public HttpResponse configureAndExecute(HttpUriRequest request, HttpContext context)
+ throws ClientProtocolException, IOException {
+ return execute(configureRequest(request), context);
+ }
+
+ public HttpClient getClient() {
+ return client;
+ }
+
+ public IProxyService getProxyService() {
+ return proxyService;
+ }
+
+ private IProxyData getProxyData(URI uri) {
+ return proxyService == null ? null : ProxyHelper.getProxyData(uri, proxyService);
+ }
+
+ private HttpHost getProxyHost(IProxyData proxy) {
+ if (IProxyData.HTTPS_PROXY_TYPE.equals(proxy.getType()) || IProxyData.HTTP_PROXY_TYPE.equals(proxy.getType())) {
+ return new HttpHost(proxy.getHost(), proxy.getPort());
+ }
+ //SOCKS proxies are handled by Java on the socket level
+ return null;
+ }
+
+ private void configureProxy(URI uri, HttpClientContext context, RequestConfig.Builder builder) throws IOException {
+ IProxyData proxy = getProxyData(uri);
+ if (proxy != null) {
+ builder.setProxy(getProxyHost(proxy));
+ setProxyAuthentication(context, proxy);
+ } else {
+ builder.setProxy(null);
+ }
+ }
+
+ private void setProxyAuthentication(HttpClientContext context, IProxyData proxy) throws IOException {
+ String proxyUserID;
+ HttpHost proxyHost;
+ if ((proxyUserID = proxy.getUserId()) != null && (proxyHost = getProxyHost(proxy)) != null) {
+ String domainUserID = NTLMDomainUtil.getNTLMUserName(proxyUserID);
+ String password = proxy.getPassword();
+ String domain = NTLMDomainUtil.getNTLMUserDomain(proxyUserID);
+ if (domain != null || !proxyUserID.equals(domainUserID)) {
+ String workstation = NTLMDomainUtil.getNTLMWorkstation();
+ setAuth(context, new AuthScope(proxyHost, AuthScope.ANY_REALM, "ntlm"), //$NON-NLS-1$
+ new NTCredentials(domainUserID, password, workstation, domain));
+ } else {
+ setAuth(context, new AuthScope(proxyHost, AuthScope.ANY_REALM, AuthScope.ANY_SCHEME),
+ new UsernamePasswordCredentials(proxyUserID, password));
+ }
+ }
+ }
+
+ private void setAuth(HttpClientContext clientContext, AuthScope authScope, Credentials credentials) {
+ CredentialsProvider authStore = clientContext.getCredentialsProvider();
+ if (authStore == null) {
+ authStore = new BasicCredentialsProvider();
+ authStore = new ChainedCredentialsProvider(authStore, this.context.getCredentialsProvider());
+ clientContext.setCredentialsProvider(authStore);
+ }
+ authStore.setCredentials(authScope, credentials);
+ }
+}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientTransport.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientTransport.java
index 103bcdbb..ec175a2d 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientTransport.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientTransport.java
@@ -21,14 +21,14 @@ import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;
import org.apache.http.HttpEntity;
+import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
-import org.apache.http.client.fluent.Executor;
-import org.apache.http.client.fluent.Request;
-import org.apache.http.client.fluent.Response;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpUriRequest;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
@@ -37,7 +37,11 @@ import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
import org.eclipse.epp.internal.mpc.core.util.UserAgentUtil;
import org.eclipse.epp.mpc.core.service.ITransport;
import org.eclipse.epp.mpc.core.service.ServiceUnavailableException;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+@Component(name = "org.eclipse.epp.mpc.core.transport.http", service = { HttpClientTransport.class,
+ ITransport.class })
public class HttpClientTransport implements ITransport {
public static final String USER_AGENT;
@@ -72,36 +76,30 @@ public class HttpClientTransport implements ITransport {
USER_AGENT = UserAgentUtil.computeUserAgent();
}
- private final HttpClient client;
-
- private final Executor executor;
-
- public HttpClientTransport() {
- HttpClientFactory httpClientFactory = new HttpClientFactory();
- client = httpClientFactory.build();
- executor = httpClientFactory.getExecutor();
- }
+ private HttpClientService clientService;
public HttpClient getClient() {
- return client;
+ return clientService.getClient();
}
- public Executor getExecutor() {
- return executor;
+ @Reference
+ public void bindHttpClientService(HttpClientService service) {
+ this.clientService = service;
}
- protected Response execute(Request request, URI uri) throws ClientProtocolException, IOException {
- return HttpClientProxyUtil.proxyAuthentication(executor, uri).execute(request);
+
+ protected HttpResponse execute(HttpUriRequest request) throws ClientProtocolException, IOException {
+ return clientService.execute(request);
}
- protected Request configureRequest(Request request, URI uri) {
- return request.viaProxy(HttpClientProxyUtil.getProxyHost(uri));
+ protected HttpRequest configureRequest(HttpUriRequest request) {
+ return clientService.configureRequest(request);
}
@Override
public InputStream stream(URI location, IProgressMonitor monitor)
throws FileNotFoundException, ServiceUnavailableException, CoreException {
try {
- return createStreamingRequest().execute(location);
+ return createStreamingRequest().execute(clientService, location);
} catch (HttpResponseException e) {
int statusCode = e.getStatusCode();
switch (statusCode) {
@@ -121,18 +119,17 @@ public class HttpClientTransport implements ITransport {
}
protected RequestTemplate<InputStream> createStreamingRequest() {
- return new RequestTemplate<InputStream>(this) {
+ return new RequestTemplate<InputStream>() {
@Override
- protected Request createRequest(URI uri) {
- return Request.Get(uri);
+ protected HttpUriRequest createRequest(URI uri) {
+ return new HttpGet(uri);
}
@Override
- protected InputStream handleResponse(Response response) throws ClientProtocolException, IOException {
- HttpResponse returnResponse = response.returnResponse();
- HttpEntity entity = returnResponse.getEntity();
- StatusLine statusLine = returnResponse.getStatusLine();
+ protected InputStream handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
+ HttpEntity entity = response.getEntity();
+ StatusLine statusLine = response.getStatusLine();
handleResponseStatus(statusLine.getStatusCode(), statusLine.getReasonPhrase());
return handleResponseEntity(entity);
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientTransportFactory.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientTransportFactory.java
index 2a332012..ff6c5df6 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientTransportFactory.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientTransportFactory.java
@@ -14,7 +14,13 @@ package org.eclipse.epp.internal.mpc.core.transport.httpclient;
import org.eclipse.epp.mpc.core.service.ITransport;
import org.eclipse.epp.mpc.core.service.ITransportFactory;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+@Component(name = "org.eclipse.epp.mpc.core.transport.http.factory", service = { HttpClientTransportFactory.class,
+ ITransportFactory.class })
public class HttpClientTransportFactory implements ITransportFactory {
private HttpClientTransport transport;
@@ -28,6 +34,7 @@ public class HttpClientTransportFactory implements ITransportFactory {
this.transport = transport;
}
+ @Reference(name = "org.eclipse.epp.mpc.core.transport.http", unbind = "unbindTransport", cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC)
public void bindTransport(HttpClientTransport transport) {
setTransport(transport);
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpServiceContext.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpServiceContext.java
new file mode 100644
index 00000000..5b16c348
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpServiceContext.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2018 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.epp.internal.mpc.core.transport.httpclient;
+
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+public class HttpServiceContext {
+
+ private final CloseableHttpClient client;
+
+ private final CookieStore cookieStore;
+
+ private final CredentialsProvider credentialsProvider;
+
+ private final CredentialsProvider credentialsCacheProvider;
+
+ private final CredentialsProvider initialCredentialsProvider;
+
+ HttpServiceContext(CloseableHttpClient client, CookieStore cookieStore, CredentialsProvider credentialsProvider,
+ CredentialsProvider initialCredentialsProvider, CredentialsProvider credentialsCacheProvider) {
+ this.client = client;
+ this.cookieStore = cookieStore;
+ this.credentialsProvider = credentialsProvider;
+ this.initialCredentialsProvider = initialCredentialsProvider;
+ this.credentialsCacheProvider = credentialsCacheProvider;
+ }
+
+ public CloseableHttpClient getClient() {
+ return client;
+ }
+
+ public CookieStore getCookieStore() {
+ return cookieStore;
+ }
+
+ public CredentialsProvider getCredentialsProvider() {
+ return credentialsProvider;
+ }
+
+ CredentialsProvider getInitialCredentialsProvider() {
+ return initialCredentialsProvider;
+ }
+
+ CredentialsProvider getCredentialsCacheProvider() {
+ return credentialsCacheProvider;
+ }
+}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientProxyUtil.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/NTLMDomainUtil.java
index 44fc9851..33f7e1ab 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/HttpClientProxyUtil.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/NTLMDomainUtil.java
@@ -12,20 +12,10 @@
*/
package org.eclipse.epp.internal.mpc.core.transport.httpclient;
-import java.io.IOException;
import java.net.InetAddress;
-import java.net.URI;
import java.net.UnknownHostException;
-import org.apache.http.HttpHost;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.NTCredentials;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.fluent.Executor;
-import org.eclipse.core.net.proxy.IProxyData;
-import org.eclipse.core.net.proxy.IProxyService;
import org.eclipse.core.runtime.Platform;
-import org.eclipse.epp.internal.mpc.core.util.ProxyHelper;
/**
* This code is based on {@link org.eclipse.userstorage.internal.util.ProxyUtil} and has been copied here to avoid
@@ -35,7 +25,7 @@ import org.eclipse.epp.internal.mpc.core.util.ProxyHelper;
* @author Carsten Reckord
*/
@SuppressWarnings("restriction")
-final class HttpClientProxyUtil {
+final class NTLMDomainUtil {
private static final String PROP_HTTP_AUTH_NTLM_DOMAIN = "http.auth.ntlm.domain";
private static final String ENV_USER_DOMAIN = "USERDOMAIN";
@@ -46,44 +36,7 @@ final class HttpClientProxyUtil {
private static String workstation;
- private HttpClientProxyUtil() {
- }
-
- public static HttpHost getProxyHost(URI uri) {
- IProxyData proxy = ProxyHelper.getProxyData(uri);
- if (proxy != null) {
- if (IProxyData.HTTPS_PROXY_TYPE.equals(proxy.getType())
- || IProxyData.HTTP_PROXY_TYPE.equals(proxy.getType())) {
- return new HttpHost(proxy.getHost(), proxy.getPort(), proxy.getType());
- }
- //SOCKS proxies are handled by Java on the socket level
- return null;
- }
-
- return null;
- }
-
- public static Executor proxyAuthentication(Executor executor, URI uri)
- throws IOException {
- IProxyData proxy = ProxyHelper.getProxyData(uri);
- if (proxy != null) {
- HttpHost proxyHost = new HttpHost(proxy.getHost(), proxy.getPort());
- String proxyUserID = proxy.getUserId();
- if (proxyUserID != null) {
- String domainUserID = getNTLMUserName(proxyUserID);
- String password = proxy.getPassword();
- String domain = getNTLMUserDomain(proxyUserID);
- if (domain != null || !proxyUserID.equals(domainUserID)) {
- String workstation = getNTLMWorkstation();
- executor.auth(new AuthScope(proxyHost, AuthScope.ANY_REALM, "ntlm"),
- new NTCredentials(domainUserID, password, workstation, domain));
- }
- return executor.auth(new AuthScope(proxyHost, AuthScope.ANY_REALM, AuthScope.ANY_SCHEME),
- new UsernamePasswordCredentials(proxyUserID, password));
- }
- }
-
- return executor;
+ private NTLMDomainUtil() {
}
public static String getNTLMWorkstation() {
@@ -165,15 +118,4 @@ final class HttpClientProxyUtil {
return userName;
}
-
- private static IProxyData getProxyData(IProxyService proxyService, URI uri) {
- if (proxyService != null) {
- IProxyData[] proxies = proxyService.select(uri);
- if (proxies.length != 0) {
- return proxies[0];
- }
- }
-
- return null;
- }
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/RequestTemplate.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/RequestTemplate.java
index e8dcbfea..607f134f 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/RequestTemplate.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/RequestTemplate.java
@@ -24,98 +24,41 @@ import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpResponseException;
-import org.apache.http.client.fluent.Request;
-import org.apache.http.client.fluent.Response;
import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.util.EntityUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
public abstract class RequestTemplate<T> {
- private HttpClientTransport transport;
-
- private ServiceReference<HttpClientTransport> transportReference;
-
- public RequestTemplate() {
- }
-
- protected RequestTemplate(HttpClientTransport transport) {
- this.transport = transport;
- }
public String getUserAgent() {
return HttpClientTransport.USER_AGENT;
}
- public T execute(URI uri) throws ClientProtocolException, IOException {
- if (transport != null) {
- return executeImpl(uri);
- }
- try {
- acquireTransport();
- return executeImpl(uri);
- } finally {
- releaseTransport();
- }
- }
-
- private void releaseTransport() {
- ServiceReference<?> reference = transportReference;
- if (reference != null) {
- transport = null;
- transportReference = null;
- Bundle bundle = reference.getBundle();
- if (bundle != null) {
- bundle.getBundleContext().ungetService(reference);
- }
- }
- }
-
- private void acquireTransport() {
- Bundle bundle = FrameworkUtil.getBundle(getClass());
- BundleContext bundleContext = bundle.getBundleContext();
- ServiceReference<HttpClientTransport> serviceReference = bundleContext
- .getServiceReference(HttpClientTransport.class);
- if (serviceReference == null) {
- throw new IllegalStateException();
- }
- HttpClientTransport transport = bundleContext.getService(serviceReference);
- if (transport == null) {
- throw new IllegalStateException();
- }
- this.transportReference = serviceReference;
- this.transport = transport;
- }
-
- protected T executeImpl(URI uri) throws ClientProtocolException, IOException {
- Request request = createRequest(uri);
- request = configureRequest(request, uri);
- Response response = transport.execute(request, uri);
+ public T execute(HttpClientService client, URI uri) throws ClientProtocolException, IOException {
+ HttpUriRequest request = createRequest(uri);
+ request = configureRequest(client, request);
+ HttpResponse response = client.execute(request);
return handleResponse(response);
}
- protected abstract Request createRequest(URI uri);
+ protected abstract HttpUriRequest createRequest(URI uri);
- protected Request configureRequest(Request request, URI uri) {
+ protected HttpUriRequest configureRequest(HttpClientService client, HttpUriRequest request) {
request.setHeader(HttpHeaders.USER_AGENT, getUserAgent());
- return transport.configureRequest(request, uri);
+ return client.configureRequest(request);
}
- protected T handleResponse(Response response) throws ClientProtocolException, IOException {
- return response.handleResponse(response1 -> {
- HttpEntity entity = null;
- try {
- final StatusLine statusLine = response1.getStatusLine();
- entity = response1.getEntity();
- handleResponseStatus(statusLine.getStatusCode(), statusLine.getReasonPhrase());
- return handleResponseEntity(entity);
- } finally {
- closeResponse(response1, entity);
- }
- });
+ protected T handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
+ HttpEntity entity = null;
+ try {
+ final StatusLine statusLine = response.getStatusLine();
+ entity = response.getEntity();
+ handleResponseStatus(statusLine.getStatusCode(), statusLine.getReasonPhrase());
+ return handleResponseEntity(entity);
+ } finally {
+ closeResponse(response, entity);
+ }
}
protected T handleResponseEntity(HttpEntity entity) throws IOException {
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/SystemCredentialsProvider.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/SystemCredentialsProvider.java
index c3988fae..1572a8e4 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/SystemCredentialsProvider.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/transport/httpclient/SystemCredentialsProvider.java
@@ -27,15 +27,15 @@ public class SystemCredentialsProvider extends SystemDefaultCredentialsProvider
String domain = ntCredentials.getDomain();
String userName = ntCredentials.getUserName();
String workstation = ntCredentials.getWorkstation();
- String strippedUserName = HttpClientProxyUtil.getNTLMUserName(userName);
+ String strippedUserName = NTLMDomainUtil.getNTLMUserName(userName);
if (domain == null || !strippedUserName.equals(userName)) {
- domain = HttpClientProxyUtil.getNTLMUserDomain(userName);
+ domain = NTLMDomainUtil.getNTLMUserDomain(userName);
if (domain != null) {
userName = strippedUserName;
}
}
if (workstation == null) {
- workstation = HttpClientProxyUtil.getNTLMWorkstation();
+ workstation = NTLMDomainUtil.getNTLMWorkstation();
}
credentials = new NTCredentials(userName, ntCredentials.getPassword(), workstation, domain);
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/FallbackTransportFactory.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/FallbackTransportFactory.java
index c68a5060..87a4d7f3 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/FallbackTransportFactory.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/FallbackTransportFactory.java
@@ -38,11 +38,13 @@ import org.osgi.framework.ServiceReference;
public class FallbackTransportFactory implements ITransportFactory {
private static final class FallbackTransport implements ITransport {
- private ITransport primaryTransport;
+ private final ITransport primaryTransport;
- private final ITransport fallbackTransport;
+ private ITransport fallbackTransport;
- public FallbackTransport(ITransport primaryTransport, ITransport fallbackTransport) {
+ private boolean primaryDisabled = false;
+
+ FallbackTransport(ITransport primaryTransport, ITransport fallbackTransport) {
super();
this.primaryTransport = primaryTransport;
this.fallbackTransport = fallbackTransport;
@@ -59,11 +61,12 @@ public class FallbackTransportFactory implements ITransportFactory {
throws FileNotFoundException, ServiceUnavailableException, CoreException {
connectionAttempts++;
if (connectionAttempts > 10 && connectionFailures / (double) connectionAttempts > 0.75) {
- MarketplaceClientCore.getLog().log(new Status(IStatus.INFO, MarketplaceClientCore.BUNDLE_ID,
+ MarketplaceClientCore.getLog()
+ .log(new Status(IStatus.INFO, MarketplaceClientCore.BUNDLE_ID,
NLS.bind(Messages.FallbackTransportFactory_disablingTransport, primaryTransport)));
- primaryTransport = null;
+ primaryDisabled = true;
}
- if (primaryTransport == null) {
+ if (primaryTransport == null || primaryDisabled) {
return fallbackTransport.stream(location, monitor);
}
InputStream stream;
@@ -126,6 +129,8 @@ public class FallbackTransportFactory implements ITransportFactory {
boolean fallbackSucceeded = false;
try {
InputStream fallbackStream = fallbackTransport.stream(location, monitor);
+ BufferedInputStream buffered = new BufferedInputStream(fallbackStream);
+ tryBuffer(buffered);
fallbackSucceeded = true;
String problemKey = ex.getClass().getName() + ": " + ex.getMessage() + "\n\t" //$NON-NLS-1$//$NON-NLS-2$
+ ex.getStackTrace()[0];
@@ -136,7 +141,9 @@ public class FallbackTransportFactory implements ITransportFactory {
fallbackTransport)));
}
- return fallbackStream;
+ return buffered;
+ } catch (Exception fallbackEx) {
+ ex.addSuppressed(fallbackEx);
} finally {
if (!fallbackSucceeded) {
//fallback didn't work either - probably something unrelated to transport going on, so don't count this as a transport failure
@@ -146,25 +153,46 @@ public class FallbackTransportFactory implements ITransportFactory {
}
return null;
}
+
+ void setFallbackTransport(ITransport fallbackTransport) {
+ this.fallbackTransport = fallbackTransport;
+ }
+
+ public ITransport getPrimaryTransport() {
+ return primaryTransport;
+ }
+
+ public ITransport getFallbackTransport() {
+ return fallbackTransport;
+ }
}
private ITransportFactory primaryFactory;
private ITransportFactory secondaryFactory;
+ private FallbackTransport transport;
+
public FallbackTransportFactory() {
super();
// ignore
}
@Override
- public ITransport getTransport() {
+ public synchronized ITransport getTransport() {
ITransportFactory delegateFactory = getFallbackFactory();
+ ITransport primaryTransport = primaryFactory.getTransport();
if (delegateFactory == null) {
- return primaryFactory.getTransport();
+ return primaryTransport;
}
- return new FallbackTransport(primaryFactory.getTransport(), delegateFactory.getTransport());
+ ITransport secondaryTransport = delegateFactory.getTransport();
+
+ if (transport == null || transport.getPrimaryTransport() != primaryTransport
+ || transport.getFallbackTransport() != secondaryTransport) {
+ transport = new FallbackTransport(primaryTransport, secondaryTransport);
+ }
+ return transport;
}
public ITransportFactory getFallbackFactory() {
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/HttpUtil.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/HttpUtil.java
deleted file mode 100644
index a0bf302b..00000000
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/HttpUtil.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2018 The Eclipse Foundation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Yatta Solutions - initial API and implementation
- *******************************************************************************/
-package org.eclipse.epp.internal.mpc.core.util;
-
-import org.apache.http.HttpHost;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.client.HttpClient;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
-import org.eclipse.core.net.proxy.IProxyData;
-import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
-
-/**
- * @author Carsten Reckord
- */
-public class HttpUtil {
-
- public static HttpClient createHttpClient(String baseUri) {
- HttpClientBuilder hcBuilder = HttpClients.custom();
- hcBuilder.setUserAgent(MarketplaceClientCore.BUNDLE_ID);
-
- if (baseUri != null) {
- configureProxy(hcBuilder, baseUri);
- }
-
- return hcBuilder.build();
- }
-
- public static void configureProxy(HttpClientBuilder hcBuilder, String url) {
- final IProxyData proxyData = ProxyHelper.getProxyData(url);
- if (proxyData != null && !IProxyData.SOCKS_PROXY_TYPE.equals(proxyData.getType())) {
- HttpHost proxy = new HttpHost(proxyData.getHost(), proxyData.getPort());
- DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
- hcBuilder.setRoutePlanner(routePlanner);
- if (proxyData.isRequiresAuthentication()) {
- CredentialsProvider provider = new BasicCredentialsProvider();
- provider.setCredentials(new AuthScope(proxyData.getHost(), proxyData.getPort()),
- new UsernamePasswordCredentials(proxyData.getUserId(), proxyData.getPassword()));
- hcBuilder.setDefaultCredentialsProvider(provider);
- }
- }
- }
-}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ProxyAuthenticator.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ProxyAuthenticator.java
deleted file mode 100644
index 30365545..00000000
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ProxyAuthenticator.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2018 The Eclipse Foundation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * The Eclipse Foundation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.epp.internal.mpc.core.util;
-
-import java.net.Authenticator;
-import java.net.InetAddress;
-import java.net.PasswordAuthentication;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.text.MessageFormat;
-
-import org.eclipse.core.net.proxy.IProxyData;
-import org.eclipse.core.net.proxy.IProxyService;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtension;
-import org.eclipse.core.runtime.RegistryFactory;
-import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
-import org.eclipse.osgi.util.NLS;
-
-class ProxyAuthenticator extends Authenticator {
- private static final String EGIT_AUTHENTICATOR_CLASS = "org.eclipse.egit.core.EclipseAuthenticator"; //$NON-NLS-1$
-
- private final Authenticator delegate;
-
- private final Authenticator previousAuthenticator;
-
- public ProxyAuthenticator(Authenticator delegate) {
- if (delegate instanceof ProxyAuthenticator) {
- delegate = ((ProxyAuthenticator) delegate).getDelegate();
- }
- this.previousAuthenticator = delegate;
- this.delegate = fixDelegate(delegate);
- }
-
- private static Authenticator fixDelegate(Authenticator delegate) {
- if (delegate == null) {
- return null;
- }
- if (EGIT_AUTHENTICATOR_CLASS.equals(delegate.getClass().getName())) {
- Authenticator replacement = getPluggedInNonEGitAuthenticator();
- if (replacement != null) {
- return replacement;
- }
- }
- return delegate;
- }
-
- private static Authenticator getPluggedInNonEGitAuthenticator() {
- @SuppressWarnings("restriction")
- IExtension[] extensions = RegistryFactory.getRegistry()
- .getExtensionPoint(org.eclipse.core.internal.net.Activator.ID,
- org.eclipse.core.internal.net.Activator.PT_AUTHENTICATOR)
- .getExtensions();
- if (extensions.length == 0) {
- return null;
- }
- IConfigurationElement config = null;
- for (IExtension extension : extensions) {
- IConfigurationElement[] configs = extension.getConfigurationElements();
- if (configs.length == 0) {
- continue;
- }
- String className = configs[0].getAttribute("class"); //$NON-NLS-1$
- if (className != null && !EGIT_AUTHENTICATOR_CLASS.equals(className)) {
- config = configs[0];
- break;
- }
- }
- if (config != null) {
- try {
- return (Authenticator) config.createExecutableExtension("class");//$NON-NLS-1$
- } catch (CoreException ex) {
- MarketplaceClientCore.error(NLS.bind("Unable to instantiate authenticator {0}", //$NON-NLS-1$
- (new Object[] { config.getDeclaringExtension().getUniqueIdentifier() })), ex);
- }
- }
- return null;
- }
-
- private boolean hostMatches(final IProxyData proxy) {
- String proxyHost = proxy.getHost();
- if (proxyHost == null) {
- return false;
- }
- try {
- InetAddress requestingAddress = getRequestingSite();
- if (requestingAddress != null) {
- final InetAddress proxyAddress = InetAddress.getByName(proxyHost);
- return proxyAddress.equals(requestingAddress);
- }
- } catch (UnknownHostException err) {
- return false;
- }
- String requestingHost = getRequestingHost();
- if (requestingHost != null && requestingHost.equals(proxyHost)) {
- return true;
- }
- return false;
- }
-
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- IProxyService proxyService = ProxyHelper.getProxyService();
- if (proxyService != null && proxyService.isProxiesEnabled()) {
- URL requestingURL = getRequestingURL();
- IProxyData[] proxies;
- if (requestingURL == null) {
- proxies = proxyService.getProxyData();
- } else {
- try {
- proxies = proxyService.select(requestingURL.toURI());
- } catch (URISyntaxException e) {
- proxies = proxyService.getProxyData();
- }
- }
-
- for (IProxyData proxyData : proxies) {
- // make sure we don't hand out credentials to the wrong proxy
- if (proxyData.isRequiresAuthentication() && proxyData.getPort() == getRequestingPort()
- && hostMatches(proxyData)) {
- String userId = proxyData.getUserId();
- String password = proxyData.getPassword();
- if (userId != null && password != null) {
- return new PasswordAuthentication(userId, password.toCharArray());
- }
- }
- }
- }
- if (delegate != null) {
- // Pass on to previously registered authenticator
- // Eclipse UI bundle registers one to query credentials from user
- try {
- Authenticator.setDefault(delegate);
- String requestingHost = getRequestingHost();
- InetAddress requestingSite = getRequestingSite();
- int requestingPort = getRequestingPort();
- String requestingProtocol = getRequestingProtocol();
- String requestingPrompt = getRequestingPrompt();
- String requestingScheme = getRequestingScheme();
- URL requestingURL = getRequestingURL();
- RequestorType requestorType = getRequestorType();
- if (requestingSite == null) {
- try {
- requestingSite = InetAddress.getByName(requestingHost);
- } catch (Exception ex) {
- //ignore
- }
- }
- if (requestingPrompt == null) {
- //Help the Eclipse UI password dialog with its prompt
- String promptHost = requestingSite == null ? String.format("%s:%s", requestingHost, requestingPort) //$NON-NLS-1$
- : requestingHost == null ? requestingSite.getHostName() : requestingHost;
- String promptType = requestorType.toString().toLowerCase();
- requestingPrompt = MessageFormat.format(Messages.ProxyAuthenticator_prompt, requestingScheme,
- promptType, promptHost);
- }
- return Authenticator.requestPasswordAuthentication(requestingHost, requestingSite, requestingPort,
- requestingProtocol, requestingPrompt, requestingScheme, requestingURL, requestorType);
- } finally {
- Authenticator.setDefault(this);
- }
- }
- return null;
- }
-
- public Authenticator getDelegate() {
- return delegate;
- }
-
- public void install() {
- Authenticator.setDefault(this);
- }
-
- public void uninstall() {
- synchronized (Authenticator.class) {
- Authenticator defaultAuthenticator = ProxyHelper.getDefaultAuthenticator();
- if (defaultAuthenticator == this) {
- Authenticator.setDefault(previousAuthenticator);
- }
- }
- }
-} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ProxyHelper.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ProxyHelper.java
index 26df427e..9e16e226 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ProxyHelper.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ProxyHelper.java
@@ -12,70 +12,18 @@
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.util;
-import java.lang.reflect.Field;
-import java.net.Authenticator;
import java.net.URI;
import java.net.URISyntaxException;
import org.eclipse.core.net.proxy.IProxyData;
import org.eclipse.core.net.proxy.IProxyService;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
-import org.eclipse.epp.internal.mpc.core.MarketplaceClientCorePlugin;
-import org.osgi.util.tracker.ServiceTracker;
/**
* @author Carsten Reckord
*/
public class ProxyHelper {
-// private static ProxyAuthenticator authenticator;
- @SuppressWarnings("rawtypes")
- private static ServiceTracker proxyServiceTracker;
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public static synchronized void acquireProxyService() {
- if (proxyServiceTracker == null) {
- proxyServiceTracker = new ServiceTracker(MarketplaceClientCorePlugin.getBundle().getBundleContext(),
- IProxyService.class.getName(), null);
- proxyServiceTracker.open();
- }
-// installAuthenticator();
- }
-
- public static void installAuthenticator() {
-// synchronized (Authenticator.class) {
-// Authenticator defaultAuthenticator = getDefaultAuthenticator();
-// if (authenticator == null || authenticator != defaultAuthenticator) {
-// if (defaultAuthenticator instanceof ProxyAuthenticator) {
-// authenticator = (ProxyAuthenticator) defaultAuthenticator;
-// } else {
-// authenticator = new ProxyAuthenticator(defaultAuthenticator);
-// }
-// authenticator.install();
-// }
-// }
- }
-
- public static synchronized void releaseProxyService() {
-// uninstallAuthenticator();
- if (proxyServiceTracker != null) {
- proxyServiceTracker.close();
- }
- }
-
- public static void uninstallAuthenticator() {
-// synchronized (Authenticator.class) {
-// if (authenticator != null) {
-// authenticator.uninstall();
-// authenticator = null;
-// }
-// }
- }
-
- public static IProxyData getProxyData(String url) {
- final IProxyService proxyService = getProxyService();
+ public static IProxyData getProxyData(String url, IProxyService proxyService) {
if (proxyService != null) {
URI uri;
try {
@@ -88,8 +36,7 @@ public class ProxyHelper {
return null;
}
- public static IProxyData getProxyData(URI uri) {
- final IProxyService proxyService = getProxyService();
+ public static IProxyData getProxyData(URI uri, IProxyService proxyService) {
if (proxyService != null) {
return doGetProxyData(proxyService, uri);
}
@@ -111,28 +58,4 @@ public class ProxyHelper {
}
return null;
}
-
- protected static IProxyService getProxyService() {
- return proxyServiceTracker == null ? null : (IProxyService) proxyServiceTracker.getService();
- }
-
- static Authenticator getDefaultAuthenticator() {
- try {
- final Field authenticatorField = Authenticator.class.getDeclaredField("theAuthenticator"); //$NON-NLS-1$
- final boolean accessible = authenticatorField.isAccessible();
- try {
- if (!accessible) {
- authenticatorField.setAccessible(true);
- }
- return (Authenticator) authenticatorField.get(null);
- } finally {
- if (!accessible) {
- authenticatorField.setAccessible(false);
- }
- }
- } catch (Exception e) {
- MarketplaceClientCore.getLog().log(new Status(IStatus.WARNING, MarketplaceClientCore.BUNDLE_ID, Messages.ProxyHelper_replacingAuthenticator, e));
- }
- return null;
- }
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ServiceUtil.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ServiceUtil.java
index 5a0912d1..74738bbd 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ServiceUtil.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ServiceUtil.java
@@ -25,6 +25,7 @@ import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentConstants;
@@ -186,4 +187,11 @@ public class ServiceUtil {
ServiceReference<T> reference = registration.getReference();
return reference == null ? null : getService(reference);
}
+
+ public static <T> T getService(Class<?> context, Class<T> serviceType) {
+ BundleContext bundleContext = FrameworkUtil.getBundle(context).getBundleContext();
+ ServiceReference<T> serviceReference = bundleContext == null ? null
+ : bundleContext.getServiceReference(serviceType);
+ return serviceReference == null ? null : bundleContext.getService(serviceReference);
+ }
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/TransportFactory.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/TransportFactory.java
index 298e611d..3ebbae02 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/TransportFactory.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/TransportFactory.java
@@ -44,6 +44,9 @@ import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentConstants;
import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
@@ -87,6 +90,10 @@ public abstract class TransportFactory implements ITransportFactory {
.getProperty(ECF_EXCLUDES_PROPERTY);
if (excludeContributors != null && excludeContributors.contains(ECF_HTTPCLIENT4_TRANSPORT_ID)) {
disabledTransportsStr += "," + HTTP_TRANSPORT_WRAPPER_ID + "," + HTTP_TRANSPORT_FACTORY_ID; //$NON-NLS-1$//$NON-NLS-2$
+ } else if (disabledTransportsStr.contains(HTTP_TRANSPORT_WRAPPER_ID)) {
+ disabledTransportsStr += "," + HTTP_TRANSPORT_FACTORY_ID; //$NON-NLS-1$
+ } else if (disabledTransportsStr.contains(HTTP_TRANSPORT_FACTORY_ID)) {
+ disabledTransportsStr += "," + HTTP_TRANSPORT_WRAPPER_ID; //$NON-NLS-1$
}
Set<String> disabledTransports = new HashSet<>();
StringBuilder bldr = new StringBuilder("(&"); //$NON-NLS-1$
@@ -105,6 +112,8 @@ public abstract class TransportFactory implements ITransportFactory {
return disabledTransportsFilter;
}
+ @Component(name = "org.eclipse.epp.mpc.core.transportfactory.legacy", property = {
+ "org.eclipse.epp.mpc.core.service.transport.legacy:Boolean=true", "service.ranking:Integer=-2147483647" })
public static final class LegacyFactory implements ITransportFactory {
private ITransportFactory delegate;
@@ -122,6 +131,7 @@ public abstract class TransportFactory implements ITransportFactory {
return delegate.getTransport();
}
+ @Activate
public void activate(ComponentContext context) throws InvalidSyntaxException {
BundleContext bundleContext = context.getBundleContext();
Collection<ServiceReference<ITransportFactory>> serviceReferences = bundleContext.getServiceReferences(
@@ -152,6 +162,7 @@ public abstract class TransportFactory implements ITransportFactory {
delegateReference = null;
}
+ @Deactivate
public void deactivate(ComponentContext context) {
delegate = null;
if (delegateReference != null) {
@@ -245,7 +256,10 @@ public abstract class TransportFactory implements ITransportFactory {
lastFallbackTransport = null;
}
}
- return transportService.getTransport();
+ org.eclipse.epp.mpc.core.service.ITransport transport = transportService.getTransport();
+ if (transport != null) {
+ return transport;
+ }
} finally {
context.ungetService(serviceReference);
}
@@ -264,8 +278,15 @@ public abstract class TransportFactory implements ITransportFactory {
for (ITransportFactory factory : listAvailableFactories()) {
try {
org.eclipse.epp.mpc.core.service.ITransport transport = factory.getTransport();
- logTransportServiceFallback(serviceError, defaultServiceReference, null, factory);
- return transport;
+ if (transport != null) {
+ logTransportServiceFallback(serviceError, defaultServiceReference, null, factory);
+ return transport;
+ } else {
+ serviceError.add(new Status(IStatus.ERROR, MarketplaceClientCore.BUNDLE_ID,
+ NLS.bind(Messages.TransportFactory_LegacyFallbackCreationError,
+ factory.getClass().getName()),
+ new NullPointerException("Factory returned null transport")));
+ }
} catch (Exception ex) {
serviceError.add(new Status(IStatus.ERROR, MarketplaceClientCore.BUNDLE_ID,
NLS.bind(Messages.TransportFactory_LegacyFallbackCreationError, factory.getClass().getName()), ex));
@@ -390,17 +411,22 @@ public abstract class TransportFactory implements ITransportFactory {
return factories;
}
+ private ITransport transport;
+
@Override
@SuppressWarnings("deprecation")
- public ITransport getTransport() {
- return (location, monitor) -> {
- try {
- return invokeStream(location, monitor);
- } catch (Exception e) {
- handleStreamExceptions(e);
- }
- return null;
- };
+ public synchronized ITransport getTransport() {
+ if (transport == null && isAvailable()) {
+ transport = (location, monitor) -> {
+ try {
+ return invokeStream(location, monitor);
+ } catch (Exception e) {
+ handleStreamExceptions(e);
+ }
+ return null;
+ };
+ }
+ return transport;
}
protected abstract boolean isAvailable();
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceHelper.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceHelper.java
index 410079b0..73a2be7b 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceHelper.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceHelper.java
@@ -13,7 +13,7 @@
*******************************************************************************/
package org.eclipse.epp.mpc.core.service;
-import org.eclipse.epp.internal.mpc.core.MarketplaceClientCorePlugin;
+import org.eclipse.epp.internal.mpc.core.ServiceHelperImpl;
/**
* Convenience class to access marketplace-related OSGi services.
@@ -25,7 +25,7 @@ import org.eclipse.epp.internal.mpc.core.MarketplaceClientCorePlugin;
public abstract class ServiceHelper {
private static ServiceHelper getInstance() {
- return MarketplaceClientCorePlugin.getDefault().getServiceHelper();
+ return ServiceHelperImpl.getImplInstance();
}
protected abstract IMarketplaceServiceLocator doGetMarketplaceServiceLocator();
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/util/TransportFactoryTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/util/TransportFactoryTest.java
index 7d237da2..d0ce03a5 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/util/TransportFactoryTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/util/TransportFactoryTest.java
@@ -20,14 +20,11 @@ import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
-import java.io.IOException;
import java.io.InputStream;
-import java.lang.reflect.Constructor;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@@ -44,12 +41,9 @@ import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
-import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.AuthSchemes;
-import org.apache.http.client.fluent.Request;
-import org.apache.http.client.fluent.Response;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Lookup;
@@ -59,8 +53,10 @@ import org.apache.http.protocol.HttpContext;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.epp.internal.mpc.core.MarketplaceClientCorePlugin;
+import org.eclipse.epp.internal.mpc.core.ServiceHelperImpl;
import org.eclipse.epp.internal.mpc.core.transport.httpclient.ChainedCredentialsProvider;
import org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientCustomizer;
+import org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientService;
import org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientTransport;
import org.eclipse.epp.internal.mpc.core.transport.httpclient.HttpClientTransportFactory;
import org.eclipse.epp.internal.mpc.core.transport.httpclient.SynchronizedCredentialsProvider;
@@ -78,6 +74,8 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
+import org.mockito.internal.MockitoCore;
+import org.mockito.internal.util.MockUtil;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
@@ -120,6 +118,11 @@ public class TransportFactoryTest {
System.getProperties().remove("org.eclipse.ecf.provider.filetransfer.excludeContributors");
}
+ @Before
+ public void initServiceHelper() {
+ ServiceHelperImpl.getImplInstance();
+ }
+
@Test
public void testRegisteredFactories() throws Exception {
BundleContext context = MarketplaceClientCorePlugin.getBundle().getBundleContext();
@@ -234,26 +237,15 @@ public class TransportFactoryTest {
createFailingHttpClientTransport().stream(URI.create("http://127.0.0.1:54321"), null);
}
- private static HttpClientTransport createFailingHttpClientTransport() {
- return new HttpClientTransport() {
- @Override
- protected Response execute(Request request, URI uri) throws ClientProtocolException, IOException {
- HttpResponse mockResponse = mockResponse(mockStatusLine(503, "Expected test error"), null);
- try {
- Constructor<Response> ctor = Response.class.getDeclaredConstructor(HttpResponse.class);
- ctor.setAccessible(true);
- return ctor.newInstance(mockResponse);
- } catch (Exception e) {
- try {
- fail("Failed to create response");
- } catch (AssertionError ae) {
- ae.initCause(e);
- throw ae;
- }
- return null;
- }
- }
- };
+ private static HttpClientTransport createFailingHttpClientTransport() throws Exception {
+ HttpClientTransport transport = new HttpClientTransport();
+ HttpClientService mockClient = Mockito.mock(HttpClientService.class);
+ Mockito.when(mockClient.configureRequest(ArgumentMatchers.any())).thenAnswer(args -> args.getArgument(0));
+ Mockito.doReturn(mockResponse(mockStatusLine(503, "Expected test error"), null)).when(mockClient).execute(
+ ArgumentMatchers.any());
+
+ transport.bindHttpClientService(mockClient);
+ return transport;
}
@Test
@@ -262,9 +254,11 @@ public class TransportFactoryTest {
HttpClientTransportFactory httpClientFactory = new HttpClientTransportFactory();
httpClientFactory.setTransport(httpClientTransport);
+
+ String expectedMessage = "Secondary transport";
ITransportFactory secondaryFactory = Mockito.mock(ITransportFactory.class);
ITransport secondaryTransport = Mockito.mock(ITransport.class);
- InputStream expectedResultStream = new ByteArrayInputStream("Secondary transport".getBytes(
+ InputStream expectedResultStream = new ByteArrayInputStream(expectedMessage.getBytes(
StandardCharsets.UTF_8));
Mockito.when(secondaryFactory.getTransport()).thenReturn(secondaryTransport);
Mockito.when(secondaryTransport.stream(ArgumentMatchers.<URI> any(), ArgumentMatchers.<IProgressMonitor> any())).thenReturn(
@@ -275,7 +269,10 @@ public class TransportFactoryTest {
fallbackTransportFactory.setSecondaryFactory(secondaryFactory);
InputStream stream = fallbackTransportFactory.getTransport().stream(URI.create("http://127.0.0.1:54321"), null);
- assertSame(expectedResultStream, stream);
+ byte[] resultBytes = new byte[24];
+ int read = stream.read(resultBytes);
+ String actualMessage = new String(resultBytes, 0, read, StandardCharsets.UTF_8);
+ assertEquals(expectedMessage, actualMessage);
}
@Test
@@ -304,20 +301,33 @@ public class TransportFactoryTest {
return new HttpClientTransport();
}
+ BundleContext clientServiceContext = FrameworkUtil.getBundle(HttpClientService.class).getBundleContext();
List<ServiceRegistration<?>> registrations = new ArrayList<>();
for (int i = 0; i < customizers.length; i++) {
+ MockitoCore mockitoCore = new MockitoCore();
+ for (HttpClientCustomizer customizer : customizers) {
+ if (MockUtil.isMock(customizer)) {
+ mockitoCore.clearInvocations(customizer);
+ }
+ }
HttpClientCustomizer customizer = customizers[i];
Dictionary<String, Object> serviceProperties = ServiceUtil.serviceName(
"org.eclipse.epp.mpc.core.transport.http.test.customizer." + i, ServiceUtil.serviceRanking(1000 + i,
null));
- ServiceRegistration<?> registration = FrameworkUtil.getBundle(HttpClientCustomizer.class).getBundleContext()
+ ServiceRegistration<?> registration = clientServiceContext
.registerService(HttpClientCustomizer.class, customizer, serviceProperties);
registrations.add(registration);
}
+
+ ServiceReference<HttpClientService> clientServiceRef = clientServiceContext.getServiceReference(
+ HttpClientService.class);
+ HttpClientService clientService = clientServiceContext.getService(clientServiceRef);
+
HttpClientTransport httpClientTransport;
try
{
httpClientTransport = new HttpClientTransport();
+ httpClientTransport.bindHttpClientService(clientService);
}
finally
{

Back to the top