fix: return url without port if default port protocol is used (#1511)

* fix: return url without port if default port protocol is used

* tests: set server port to 8080 and assert that all generated url use port 8080
This commit is contained in:
Florian BEZANNIER
2024-01-31 08:34:07 +01:00
committed by GitHub
parent 537a942021
commit a5dda8cb47
5 changed files with 61 additions and 11 deletions

View File

@@ -102,7 +102,7 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
String urlPattern = protocol.getRef(); String urlPattern = protocol.getRef();
for (final Entry<String, String> entry : entrySet) { for (final Entry<String, String> entry : entrySet) {
if (entry.getKey().equals(PORT_PLACEHOLDER)) { if (List.of(PORT_PLACEHOLDER,PORT_REQUEST_PLACEHOLDER).contains(entry.getKey())) {
urlPattern = urlPattern.replace(":{" + entry.getKey() + "}", urlPattern = urlPattern.replace(":{" + entry.getKey() + "}",
ObjectUtils.isEmpty(entry.getValue()) ? "" : (":" + entry.getValue())); ObjectUtils.isEmpty(entry.getValue()) ? "" : (":" + entry.getValue()));
} else { } else {
@@ -157,8 +157,8 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
if (requestUri == null) { if (requestUri == null) {
return getPort(protocol); return getPort(protocol);
} }
// if port undefined then default protocol port is used
return requestUri.getPort() > 0 ? String.valueOf(requestUri.getPort()) : getPort(protocol); return requestUri.getPort() > 0 ? String.valueOf(requestUri.getPort()) : "";
} }
private static String getRequestHost(final UrlProtocol protocol, final URI requestUri) { private static String getRequestHost(final UrlProtocol protocol, final URI requestUri) {

View File

@@ -181,6 +181,24 @@ public class PropertyBasedArtifactUrlHandlerTest {
+ SOFTWAREMODULEID + "/artifacts/" + FILENAME_ENCODE)); + SOFTWAREMODULEID + "/artifacts/" + FILENAME_ENCODE));
} }
@Test
@Description("Verfies that if default protocol port in request is used then url is returned without port")
public void urlGenerationWithPortFromRequestForHttps() throws URISyntaxException {
String protocol = "https";
final UrlProtocol proto = new UrlProtocol();
proto.setRef(
"{protocolRequest}://{hostnameRequest}:{portRequest}/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}");
proto.setProtocol(protocol);
properties.getProtocols().put("download-http", proto);
URI uri = new URI(protocol+"://anotherHost.com");
final List<ArtifactUrl> urls = urlHandlerUnderTest.getUrls(placeholder, ApiType.DDI, uri);
assertThat(urls).containsExactly(new ArtifactUrl(protocol.toUpperCase(), "download-http",
uri +"/" + TENANT + "/controller/v1/" + CONTROLLER_ID + "/softwaremodules/"
+ SOFTWAREMODULEID + "/artifacts/" + FILENAME_ENCODE));
}
@Test @Test
@Description("Verfies that the domain of the statically defined hostname is replaced with the domain of the request.") @Description("Verfies that the domain of the statically defined hostname is replaced with the domain of the request.")
public void urlGenerationWithDomainFromRequest() throws URISyntaxException { public void urlGenerationWithDomainFromRequest() throws URISyntaxException {

View File

@@ -61,7 +61,8 @@ import com.fasterxml.jackson.dataformat.cbor.CBORParser;
@TestPropertySource(locations = "classpath:/ddi-test.properties") @TestPropertySource(locations = "classpath:/ddi-test.properties")
public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrationTest { public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrationTest {
protected static final String HTTP_LOCALHOST = "http://localhost:8080/"; public static final int HTTP_PORT = 8080;
protected static final String HTTP_LOCALHOST = String.format("http://localhost:%s/",HTTP_PORT);
protected static final String CONTROLLER_BASE = "/{tenant}/controller/v1/{controllerId}"; protected static final String CONTROLLER_BASE = "/{tenant}/controller/v1/{controllerId}";
protected static final String SOFTWARE_MODULE_ARTIFACTS = CONTROLLER_BASE protected static final String SOFTWARE_MODULE_ARTIFACTS = CONTROLLER_BASE
@@ -156,7 +157,8 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
protected ResultActions performGet(final String url, final MediaType mediaType, final ResultMatcher statusMatcher, protected ResultActions performGet(final String url, final MediaType mediaType, final ResultMatcher statusMatcher,
final String... values) throws Exception { final String... values) throws Exception {
return mvc.perform(MockMvcRequestBuilders.get(url, values).accept(mediaType)) return mvc.perform(MockMvcRequestBuilders.get(url, values).accept(mediaType)
.with(new RequestOnHawkbitDefaultPortPostProcessor()))
.andDo(MockMvcResultPrinter.print()).andExpect(statusMatcher) .andDo(MockMvcResultPrinter.print()).andExpect(statusMatcher)
.andExpect(content().contentTypeCompatibleWith(mediaType)); .andExpect(content().contentTypeCompatibleWith(mediaType));
} }
@@ -242,12 +244,12 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
} }
protected String installedBaseLink(final String controllerId, final String actionId) { protected String installedBaseLink(final String controllerId, final String actionId) {
return "http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId return HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
+ "/installedBase/" + actionId; + "/installedBase/" + actionId;
} }
protected String deploymentBaseLink(final String controllerId, final String actionId) { protected String deploymentBaseLink(final String controllerId, final String actionId) {
return "http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId return HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
+ "/deploymentBase/" + actionId; + "/deploymentBase/" + actionId;
} }

View File

@@ -254,7 +254,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
.getContent().get(0); .getContent().get(0);
final String etagWithFirstUpdate = mvc final String etagWithFirstUpdate = mvc
.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId) .perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId)
.header("If-None-Match", etag).accept(MediaType.APPLICATION_JSON)) .header("If-None-Match", etag).accept(MediaType.APPLICATION_JSON).with(new RequestOnHawkbitDefaultPortPostProcessor()))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00"))) .andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
@@ -266,7 +266,8 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
assertThat(etagWithFirstUpdate).isNotNull(); assertThat(etagWithFirstUpdate).isNotNull();
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).header("If-None-Match", mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).header("If-None-Match",
etagWithFirstUpdate)).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotModified()); etagWithFirstUpdate).with(new RequestOnHawkbitDefaultPortPostProcessor()))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotModified());
// now lets finish the update // now lets finish the update
sendDeploymentActionFeedback(target, updateAction, "closed", null).andDo(MockMvcResultPrinter.print()) sendDeploymentActionFeedback(target, updateAction, "closed", null).andDo(MockMvcResultPrinter.print())
@@ -276,7 +277,8 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
// original state cannot be restored // original state cannot be restored
final String etagAfterInstallation = mvc final String etagAfterInstallation = mvc
.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId) .perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId)
.header("If-None-Match", etag).accept(MediaType.APPLICATION_JSON)) .header("If-None-Match", etag).accept(MediaType.APPLICATION_JSON)
.with(new RequestOnHawkbitDefaultPortPostProcessor()))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00"))) .andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
@@ -294,7 +296,8 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
.getContent().get(0); .getContent().get(0);
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId) mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId)
.header("If-None-Match", etagAfterInstallation).accept(MediaType.APPLICATION_JSON)) .header("If-None-Match", etagAfterInstallation).accept(MediaType.APPLICATION_JSON)
.with(new RequestOnHawkbitDefaultPortPostProcessor()))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00"))) .andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))

View File

@@ -0,0 +1,27 @@
/**
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.ddi.rest.resource;
import static org.eclipse.hawkbit.ddi.rest.resource.AbstractDDiApiIntegrationTest.HTTP_PORT;
import org.jetbrains.annotations.NotNull;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
public class RequestOnHawkbitDefaultPortPostProcessor implements RequestPostProcessor {
@NotNull
@Override
public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
request.setRemotePort(HTTP_PORT);
request.setServerPort(HTTP_PORT);
return request;
}
}