diff --git a/common-service-core/src/main/java/org/zowe/apiml/util/EurekaUtils.java b/common-service-core/src/main/java/org/zowe/apiml/util/EurekaUtils.java index 7b83e47217..9166eced1e 100644 --- a/common-service-core/src/main/java/org/zowe/apiml/util/EurekaUtils.java +++ b/common-service-core/src/main/java/org/zowe/apiml/util/EurekaUtils.java @@ -12,11 +12,14 @@ import com.netflix.appinfo.InstanceInfo; import lombok.experimental.UtilityClass; +import org.apache.commons.lang3.StringUtils; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.zowe.apiml.constants.EurekaMetadataDefinition; +import org.zowe.apiml.exception.MetadataValidationException; import java.util.Optional; +import java.util.regex.Pattern; import static org.zowe.apiml.constants.EurekaMetadataDefinition.APIML_ID; import static org.zowe.apiml.product.constants.CoreService.GATEWAY; @@ -28,19 +31,46 @@ @UtilityClass public class EurekaUtils { + public static final Pattern SERVICE_ID_PATTERN = Pattern.compile("^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"); + /** * Extract serviceId from instanceId * @param instanceId input, instanceId in format "host:service:random number to unique instanceId" * @return second part, it means serviceId. If it doesn't exist return null; */ public String getServiceIdFromInstanceId(String instanceId) { - final int startIndex = instanceId.indexOf(':'); - if (startIndex < 0) return null; + if (StringUtils.isBlank(instanceId)) { + return null; + } + String[] parts = instanceId.split(":"); + if (parts.length != 3) { + return null; + } - final int endIndex = instanceId.indexOf(':', startIndex + 1); - if (endIndex < 0) return null; + String serviceId = parts[1].trim(); + if (serviceId.isEmpty()) { + return null; + } + + return serviceId; + } - return instanceId.substring(startIndex + 1, endIndex); + /** + * Validate whether service ID is not null and conformant. + * @param serviceId the service ID + * @throws MetadataValidationException exception if the service ID is not conformant + */ + public void validateServiceId(String serviceId) { + if (StringUtils.isBlank(serviceId)) { + throw new MetadataValidationException("The service ID must not be null or empty. The service will not be registered."); + } + if (!SERVICE_ID_PATTERN.matcher(serviceId).matches()) { + String message = String.format( + "Invalid serviceId [%s]: must comply with RFC 952/1123 (only lowercase letters, digits, hyphens, max 63 chars). The service will not be registered.", + serviceId + ); + throw new MetadataValidationException(message); + } } /** diff --git a/common-service-core/src/test/java/org/zowe/apiml/util/EurekaUtilsTest.java b/common-service-core/src/test/java/org/zowe/apiml/util/EurekaUtilsTest.java index e5be5b03b6..64070e7002 100644 --- a/common-service-core/src/test/java/org/zowe/apiml/util/EurekaUtilsTest.java +++ b/common-service-core/src/test/java/org/zowe/apiml/util/EurekaUtilsTest.java @@ -14,12 +14,17 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.netflix.eureka.EurekaServiceInstance; +import org.zowe.apiml.exception.MetadataValidationException; import java.util.Collections; import java.util.Map; +import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -32,13 +37,13 @@ class EurekaUtilsTest { @Test void test() { - assertEquals("abc", EurekaUtils.getServiceIdFromInstanceId("123:abc:def:::::xyz")); assertEquals("abc", EurekaUtils.getServiceIdFromInstanceId("123:abc:def")); - assertEquals("", EurekaUtils.getServiceIdFromInstanceId("123::def")); - assertEquals("", EurekaUtils.getServiceIdFromInstanceId("::")); + assertNull(EurekaUtils.getServiceIdFromInstanceId("123:abc:def:::::xyz")); + assertNull(EurekaUtils.getServiceIdFromInstanceId("hostname:123:")); + assertNull(EurekaUtils.getServiceIdFromInstanceId("::")); + assertNull(EurekaUtils.getServiceIdFromInstanceId("123::def")); assertNull(EurekaUtils.getServiceIdFromInstanceId(":")); assertNull(EurekaUtils.getServiceIdFromInstanceId("")); - assertNull(EurekaUtils.getServiceIdFromInstanceId("abc")); } private InstanceInfo createInstanceInfo(String host, int port, int securePort, boolean isSecureEnabled) { @@ -112,4 +117,37 @@ void givenUnknownServiceId_whenGetInstanceInfo_thenReturnEmptyOptional() { } + @Nested + class WhenValidatingServiceId { + + private static Stream validServiceIds() { + return Stream.of( + Arguments.of("valid-service-id"), + Arguments.of("a".repeat(63)) + ); + } + + private static Stream invalidServiceIds() { + return Stream.of( + Arguments.of("service_id"), + Arguments.of(""), + Arguments.of(" "), + Arguments.of("Invalid@ServiceId"), + Arguments.of("a".repeat(64)) + ); + } + + @ParameterizedTest + @MethodSource("invalidServiceIds") + void givenServiceIdWithUnderscore_thenThrowMetadataValidationException(String serviceId) { + assertThrows(MetadataValidationException.class, () -> EurekaUtils.validateServiceId(serviceId)); + } + + @ParameterizedTest + @MethodSource("validServiceIds") + void testValidateServiceId_thenDoNotThrowException(String serviceId) { + assertDoesNotThrow(() -> EurekaUtils.validateServiceId(serviceId)); + } + } + } diff --git a/discoverable-client/src/main/java/org/zowe/apiml/client/service/ApiMediationClientService.java b/discoverable-client/src/main/java/org/zowe/apiml/client/service/ApiMediationClientService.java index 32de8e52ca..b1aa26624f 100644 --- a/discoverable-client/src/main/java/org/zowe/apiml/client/service/ApiMediationClientService.java +++ b/discoverable-client/src/main/java/org/zowe/apiml/client/service/ApiMediationClientService.java @@ -32,7 +32,7 @@ @Service public class ApiMediationClientService { private static final String PORT = "10013"; - private static final String SERVICE_ID = "registrationTest"; + private static final String SERVICE_ID = "registrationtest"; private static final String GATEWAY_URL = "api/v1"; private final DiscoverableClientConfig dcConfig; diff --git a/discovery-service/src/main/java/org/zowe/apiml/discovery/ApimlInstanceRegistry.java b/discovery-service/src/main/java/org/zowe/apiml/discovery/ApimlInstanceRegistry.java index 2d98b8da27..a440a6ad12 100644 --- a/discovery-service/src/main/java/org/zowe/apiml/discovery/ApimlInstanceRegistry.java +++ b/discovery-service/src/main/java/org/zowe/apiml/discovery/ApimlInstanceRegistry.java @@ -21,10 +21,13 @@ import com.netflix.eureka.resources.ServerCodecs; import com.netflix.eureka.transport.EurekaServerHttpClientFactory; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.cloud.netflix.eureka.server.InstanceRegistry; import org.springframework.cloud.netflix.eureka.server.InstanceRegistryProperties; import org.springframework.context.ApplicationContext; import org.zowe.apiml.discovery.config.EurekaConfig; +import org.zowe.apiml.exception.MetadataValidationException; +import org.zowe.apiml.util.EurekaUtils; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; @@ -34,11 +37,7 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; @@ -229,6 +228,7 @@ public boolean isExpired(long additionalLeaseMs) { */ @Override public void register(InstanceInfo info, int leaseDuration, boolean isReplication) { + isServiceIdConformant(info); info = changeServiceId(info); try { register3ArgsMethodHandle.invokeWithArguments(this, info, leaseDuration, isReplication); @@ -244,6 +244,7 @@ public void register(InstanceInfo info, int leaseDuration, boolean isReplication @Override public void register(InstanceInfo info, final boolean isReplication) { + isServiceIdConformant(info); info = changeServiceId(info); try { register2ArgsMethodHandle.invokeWithArguments(this, info, isReplication); @@ -257,6 +258,34 @@ public void register(InstanceInfo info, final boolean isReplication) { } } + /** + * Validates that the service identifiers in the {@link InstanceInfo} are conformant and mutually consistent. + * The appName must not be null or empty. Both must comply with RFC 952 and RFC 1123. + * Only lowercase letters, digits, and hyphens allowed, must not start or end with a hyphen, and must not exceed 63 characters. + * The instanceId must follow the format 'hostname:serviceId:port'. + * The serviceId extracted from the instanceId must match both appName. + * If any of these checks fail, the method will throw an exception and the registration is rejected. + * @param info the instance info + * @throws MetadataValidationException exception if any service identifier is invalid or inconsistent + */ + private void isServiceIdConformant(InstanceInfo info) { + String instanceId = info.getInstanceId(); + String appName = StringUtils.lowerCase(info.getAppName()); + + EurekaUtils.validateServiceId(appName); + String serviceId = EurekaUtils.getServiceIdFromInstanceId(instanceId); + + EurekaUtils.validateServiceId(serviceId); + + if (!serviceId.equals(appName)) { + throw new MetadataValidationException( + String.format("Inconsistent service identity: instanceId contains serviceId '%s' but appName='%s'. The service will not be registered.", + serviceId, appName) + + ); + } + } + @Override public long getNumOfRenewsInLastMin() { // to simulate APIML, it is not sending a heartbeat anymore diff --git a/discovery-service/src/main/java/org/zowe/apiml/discovery/staticdef/ServiceDefinitionProcessor.java b/discovery-service/src/main/java/org/zowe/apiml/discovery/staticdef/ServiceDefinitionProcessor.java index 6a3adf52c0..a6cf018b53 100644 --- a/discovery-service/src/main/java/org/zowe/apiml/discovery/staticdef/ServiceDefinitionProcessor.java +++ b/discovery-service/src/main/java/org/zowe/apiml/discovery/staticdef/ServiceDefinitionProcessor.java @@ -43,6 +43,7 @@ import java.util.*; import static org.zowe.apiml.constants.EurekaMetadataDefinition.*; +import static org.zowe.apiml.util.EurekaUtils.SERVICE_ID_PATTERN; /** * Processes static definition files and creates service instances @@ -208,8 +209,8 @@ private CatalogUiTile getTile(StaticRegistrationResult context, String ymlFileNa private List createInstances(StaticRegistrationResult context, String ymlFileName, Service service, Map tiles) { try { - if (service.getServiceId() == null) { - throw new ServiceDefinitionException(String.format("ServiceId is not defined in the file '%s'. The instance will not be created.", ymlFileName)); + if (service.getServiceId() == null || !SERVICE_ID_PATTERN.matcher(service.getServiceId()).matches()) { + throw new ServiceDefinitionException(String.format("ServiceId is either not defined in the file '%s' or not conformant. The instance will not be created.", ymlFileName)); } if (service.getInstanceBaseUrls() == null) { diff --git a/discovery-service/src/test/java/org/zowe/apiml/discovery/ApimlInstanceRegistryTest.java b/discovery-service/src/test/java/org/zowe/apiml/discovery/ApimlInstanceRegistryTest.java index 89975c17a4..503a2bad5b 100644 --- a/discovery-service/src/test/java/org/zowe/apiml/discovery/ApimlInstanceRegistryTest.java +++ b/discovery-service/src/test/java/org/zowe/apiml/discovery/ApimlInstanceRegistryTest.java @@ -32,6 +32,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.test.util.ReflectionTestUtils; import org.zowe.apiml.discovery.config.EurekaConfig; +import org.zowe.apiml.exception.MetadataValidationException; import java.lang.invoke.MethodHandle; import java.lang.invoke.WrongMethodTypeException; @@ -41,10 +42,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; @@ -71,7 +69,7 @@ class ApimlInstanceRegistryTest { @BeforeEach void setUp() { - standardInstance = getStandardInstance(); + standardInstance = getStandardInstance("hostname:serviceclient:10010", "serviceclient"); serverConfig = new DefaultEurekaServerConfig(); apimlInstanceRegistry = spy(new ApimlInstanceRegistry( @@ -92,6 +90,68 @@ void setUp() { ReflectionTestUtils.setField(apimlInstanceRegistry, "handleCancellationMethod", methodHandle); } + @Nested + class GivenInvalidServiceId { + + private static Stream instanceIds() { + return Stream.of( + Arguments.of( "hostname:service_client:10010", "service_client"), + Arguments.of( "hostname:service_client:10010", ""), + Arguments.of( "hostname:10010", "service_client"), + Arguments.of( "hostname:service_client:10010", "different_service_client"), + Arguments.of( "hostname:-serviceclient:10010", "-serviceclient"), + Arguments.of( "hostname:serviceclient-:10010", "serviceclient-"), + Arguments.of( "hostname:invalidserviceidididididididididididdididididididididididdidididididididididid:10010", "invalidserviceidididididididididididdididididididididididdidididididididididid"), + Arguments.of( null, "service") + ); + } + + @ParameterizedTest + @MethodSource("instanceIds") + void whenContainingUnderscore_thenThrowException(String instanceId, String appName) { + InstanceInfo wrongInstance = getStandardInstance(instanceId, appName); + + apimlInstanceRegistry = spy(new ApimlInstanceRegistry( + serverConfig, + clientConfig, + serverCodecs, + eurekaClient, + eurekaServerHttpClientFactory, + instanceRegistryProperties, + appCntx, + new EurekaConfig.Tuple(""))); + MethodHandle methodHandle = mock(MethodHandle.class); + ReflectionTestUtils.setField(apimlInstanceRegistry,"register3ArgsMethodHandle",methodHandle); + ReflectionTestUtils.setField(apimlInstanceRegistry,"handleRegistrationMethod",methodHandle); + assertThrows(MetadataValidationException.class, () -> { + apimlInstanceRegistry.register(wrongInstance, 1, false); + }); + + } + } + + @Nested + class GivenValidServiceIdWithDash { + + @Test + void thenShouldRegister() { + standardInstance = getStandardInstance("hostname:service-client:10010", "service-client"); + apimlInstanceRegistry = spy(new ApimlInstanceRegistry( + serverConfig, + clientConfig, + serverCodecs, + eurekaClient, + eurekaServerHttpClientFactory, + instanceRegistryProperties, + appCntx, + new EurekaConfig.Tuple(null))); + MethodHandle methodHandle = mock(MethodHandle.class); + ReflectionTestUtils.setField(apimlInstanceRegistry,"register2ArgsMethodHandle", methodHandle); + ReflectionTestUtils.setField(apimlInstanceRegistry,"handleRegistrationMethod", methodHandle); + assertDoesNotThrow(() -> apimlInstanceRegistry.register(standardInstance, false)); + } + } + @Nested class GivenReplacerTuple { @Nested @@ -99,7 +159,7 @@ class WhenChangeServiceId { @Test void thenChangeServicePrefix() { InstanceInfo info = apimlInstanceRegistry.changeServiceId(standardInstance); - assertEquals("helloclient", info.getInstanceId()); + assertEquals("hostname:helloclient:10010", info.getInstanceId()); assertEquals("HELLOCLIENT", info.getAppName()); assertEquals("helloclient", info.getVIPAddress()); assertEquals("HELLOCLIENT", info.getAppGroupName()); @@ -112,15 +172,15 @@ void thenChangeServicePrefix() { } private static Stream tuples() { return Stream.of( - Arguments.of("service*,hello", "helloclient"), - Arguments.of("service,hello", "helloclient"), - Arguments.of("service*,hello*", "helloclient"), - Arguments.of("service*,service", "serviceclient"), - Arguments.of("service*", "serviceclient"), - Arguments.of(",service", "serviceclient"), - Arguments.of("service,", "serviceclient"), - Arguments.of(null, "serviceclient"), - Arguments.of("different*,hello", "serviceclient") + Arguments.of("service*,hello", "hostname:helloclient:10010"), + Arguments.of("service,hello", "hostname:helloclient:10010"), + Arguments.of("service*,hello*", "hostname:helloclient:10010"), + Arguments.of("service*,service", "hostname:serviceclient:10010"), + Arguments.of("service*", "hostname:serviceclient:10010"), + Arguments.of(",service", "hostname:serviceclient:10010"), + Arguments.of("service,", "hostname:serviceclient:10010"), + Arguments.of(null, "hostname:serviceclient:10010"), + Arguments.of("different*,hello", "hostname:serviceclient:10010") ); } @@ -371,18 +431,18 @@ private Stream exceptions() { } - private InstanceInfo getStandardInstance() { + private InstanceInfo getStandardInstance(String instanceId, String appName) { return InstanceInfo.Builder.newBuilder() - .setInstanceId("serviceclient") - .setAppName("SERVICECLIENT") - .setAppGroupName("SERVICECLIENT") + .setInstanceId(instanceId) + .setAppName(appName.toUpperCase()) + .setAppGroupName(appName.toUpperCase()) .setIPAddr("192.168.0.1") .enablePort(InstanceInfo.PortType.SECURE, true) .setSecurePort(9090) .setHostName("localhost") .setSecureVIPAddress("localhost") - .setVIPAddress("serviceclient") + .setVIPAddress(appName) .setStatus(InstanceInfo.InstanceStatus.UP) .build(); } diff --git a/discovery-service/src/test/java/org/zowe/apiml/discovery/metadata/MetadataDefaultsServiceTest.java b/discovery-service/src/test/java/org/zowe/apiml/discovery/metadata/MetadataDefaultsServiceTest.java index a72b29a8b8..fca1bb5150 100644 --- a/discovery-service/src/test/java/org/zowe/apiml/discovery/metadata/MetadataDefaultsServiceTest.java +++ b/discovery-service/src/test/java/org/zowe/apiml/discovery/metadata/MetadataDefaultsServiceTest.java @@ -89,17 +89,17 @@ void updatingStaticService() { assertEquals( "TSTAPPL4", - map.get("STATIC-localhost:toAddAuth:10012").getMetadata().get(AUTHENTICATION_APPLID) + map.get("STATIC-localhost:toaddauth:10012").getMetadata().get(AUTHENTICATION_APPLID) ); assertEquals( "TSTAPPL5", - map.get("STATIC-localhost:toReplaceAuth:10012").getMetadata().get(AUTHENTICATION_APPLID) + map.get("STATIC-localhost:toreplaceauth:10012").getMetadata().get(AUTHENTICATION_APPLID) ); assertEquals( "TSTAPPL3", - map.get("STATIC-localhost:nowFixedAuth:10012").getMetadata().get(AUTHENTICATION_APPLID) + map.get("STATIC-localhost:nowfixedauth:10012").getMetadata().get(AUTHENTICATION_APPLID) ); } diff --git a/discovery-service/src/test/java/org/zowe/apiml/discovery/staticdef/ServiceDefinitionProcessorTest.java b/discovery-service/src/test/java/org/zowe/apiml/discovery/staticdef/ServiceDefinitionProcessorTest.java index 2e42335b36..16192c1432 100644 --- a/discovery-service/src/test/java/org/zowe/apiml/discovery/staticdef/ServiceDefinitionProcessorTest.java +++ b/discovery-service/src/test/java/org/zowe/apiml/discovery/staticdef/ServiceDefinitionProcessorTest.java @@ -15,7 +15,9 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; import org.zowe.apiml.message.core.Message; import org.zowe.apiml.message.core.MessageService; import org.zowe.apiml.message.log.ApimlLogger; @@ -30,6 +32,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Stream; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; @@ -313,11 +316,20 @@ void givenNoInstanceInBaseUrls_whenDefinitionIsLoaded_thenErrorIsReturned() { ); } - @Test - void givenInstanceWithoutServiceId_whenDefinitionIsLoaded_thenErrorIsReturned() { + private static Stream serviceIds() { + return Stream.of( + Arguments.of(""), + Arguments.of("seRvic_E@") + ); + } + + + @ParameterizedTest + @MethodSource("serviceIds") + void givenInstanceWithWrongServiceId_whenDefinitionIsLoaded_thenErrorIsReturned(String serviceId) { String yaml = "services:\n" + - " - serviceId: \n" + + " - serviceId: " + serviceId + " \n" + " title: Title\n" + " description: Description\n" + " catalogUiTileId: tileid\n" + @@ -331,7 +343,7 @@ void givenInstanceWithoutServiceId_whenDefinitionIsLoaded_thenErrorIsReturned() assertThatNoInstanceIsCreatedAndCorrectMessageIsProduced( result, - "ServiceId is not defined in the file 'test.yml'. The instance will not be created." + "ServiceId is either not defined in the file 'test.yml' or not conformant. The instance will not be created." ); } diff --git a/discovery-service/src/test/resources/api-defs/staticclient.yml b/discovery-service/src/test/resources/api-defs/staticclient.yml index e17d50dd7f..75531bd15b 100644 --- a/discovery-service/src/test/resources/api-defs/staticclient.yml +++ b/discovery-service/src/test/resources/api-defs/staticclient.yml @@ -23,18 +23,18 @@ services: serviceRelativeUrl: /ws - gatewayUrl: api-doc serviceRelativeUrl: /api-doc - - serviceId: toAddAuth + - serviceId: toaddauth title: Service to add auth info instanceBaseUrls: - https://localhost:10012/discoverableclient - - serviceId: toReplaceAuth + - serviceId: toreplaceauth title: Service to replace auth info instanceBaseUrls: - https://localhost:10012/discoverableclient authentication: scheme: httpBasicPassTicket applid: TSTAPPL2 - - serviceId: nowFixedAuth + - serviceId: nowfixedauth title: Service with temporary auth, althought auth is defined now instanceBaseUrls: - https://localhost:10012/discoverableclient @@ -43,16 +43,16 @@ services: applid: TSTAPPL3 additionalServiceMetadata: - - serviceId: toAddAuth + - serviceId: toaddauth authentication: scheme: httpBasicPassTicket applid: TSTAPPL4 - - serviceId: toReplaceAuth + - serviceId: toreplaceauth mode: FORCE_UPDATE authentication: scheme: httpBasicPassTicket applid: TSTAPPL5 - - serviceId: nowFixedAuth + - serviceId: nowfixedauth authentication: scheme: httpBasicPassTicket applid: TSTAPPL6 diff --git a/integration-tests/src/test/java/org/zowe/apiml/functional/gateway/AuthenticationOnDeploymentTest.java b/integration-tests/src/test/java/org/zowe/apiml/functional/gateway/AuthenticationOnDeploymentTest.java index 37aacbc729..5e09d2e35f 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/functional/gateway/AuthenticationOnDeploymentTest.java +++ b/integration-tests/src/test/java/org/zowe/apiml/functional/gateway/AuthenticationOnDeploymentTest.java @@ -74,8 +74,8 @@ void testMultipleAuthenticationSchemes() throws Exception { List ports = RandomPorts.generateUniquePorts(2); try ( - final VirtualService service1 = new VirtualService("testService", ports.get(0)); - final VirtualService service2 = new VirtualService("testService", ports.get(1)) + final VirtualService service1 = new VirtualService("testservice", ports.get(0)); + final VirtualService service2 = new VirtualService("testservice", ports.get(1)) ) { // start first instance - without passTickets service1 @@ -158,9 +158,9 @@ void testReregistration() throws Exception { List ports = RandomPorts.generateUniquePorts(3); try ( - final VirtualService service1 = new VirtualService("testService3", ports.get(0)); - final VirtualService service2 = new VirtualService("testService3", ports.get(1)); - final VirtualService service4 = new VirtualService("testService3", ports.get(2)) + final VirtualService service1 = new VirtualService("testservice3", ports.get(0)); + final VirtualService service2 = new VirtualService("testservice3", ports.get(1)); + final VirtualService service4 = new VirtualService("testservice3", ports.get(2)) ) { List serviceList = Arrays.asList(service1, service2); diff --git a/integration-tests/src/test/java/org/zowe/apiml/functional/gateway/ServiceHaModeTest.java b/integration-tests/src/test/java/org/zowe/apiml/functional/gateway/ServiceHaModeTest.java index 3bb1bc0076..5a6dbd4ea1 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/functional/gateway/ServiceHaModeTest.java +++ b/integration-tests/src/test/java/org/zowe/apiml/functional/gateway/ServiceHaModeTest.java @@ -92,8 +92,8 @@ class WhenOneIsDown { void setUp() throws LifecycleException, IOException, JSONException { List ports = RandomPorts.generateUniquePorts(2); - service1 = new VirtualService("testHaModeService1", ports.get(0)); - service2 = new VirtualService("testHaModeService1", ports.get(1)); + service1 = new VirtualService("testhamodeservice1", ports.get(0)); + service2 = new VirtualService("testhamodeservice1", ports.get(1)); service1.start(); service2.start().waitForGatewayRegistration(TIMEOUT); @@ -151,8 +151,8 @@ class OneReturns503 { void setUp() throws LifecycleException, IOException, JSONException { List ports = RandomPorts.generateUniquePorts(2); - service1 = new VirtualService("testHaModeService2", ports.get(0)); - service2 = new VirtualService("testHaModeService2", ports.get(1)); + service1 = new VirtualService("testhamodeservice2", ports.get(0)); + service2 = new VirtualService("testhamodeservice2", ports.get(1)); service1.addInstanceServlet("Http503", "/httpCode"); service2.addHttpStatusCodeServlet(HttpStatus.SC_SERVICE_UNAVAILABLE); diff --git a/integration-tests/src/test/java/org/zowe/apiml/util/service/VirtualService.java b/integration-tests/src/test/java/org/zowe/apiml/util/service/VirtualService.java index 296346429f..270f351807 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/util/service/VirtualService.java +++ b/integration-tests/src/test/java/org/zowe/apiml/util/service/VirtualService.java @@ -57,7 +57,7 @@ *

* It is recommended to use try-with-resource to be sure, service will be unregistered on the end, ie.: *

- * try (final VirtualService service = new VirtualService("testService")) { + * try (final VirtualService service = new VirtualService("testservice")) { * service * // add same servlet and setting of service * .start() diff --git a/onboarding-enabler-java/src/main/java/org/zowe/apiml/eurekaservice/client/util/EurekaInstanceConfigValidator.java b/onboarding-enabler-java/src/main/java/org/zowe/apiml/eurekaservice/client/util/EurekaInstanceConfigValidator.java index 16ce7edec6..5d57d8dc3b 100644 --- a/onboarding-enabler-java/src/main/java/org/zowe/apiml/eurekaservice/client/util/EurekaInstanceConfigValidator.java +++ b/onboarding-enabler-java/src/main/java/org/zowe/apiml/eurekaservice/client/util/EurekaInstanceConfigValidator.java @@ -16,10 +16,12 @@ import org.zowe.apiml.eurekaservice.client.config.Route; import org.zowe.apiml.eurekaservice.client.config.Ssl; import org.zowe.apiml.exception.MetadataValidationException; +import org.zowe.apiml.util.EurekaUtils; import java.util.ArrayList; import java.util.List; + /** * Class that validates a service configuration before the registration with API ML */ @@ -40,6 +42,7 @@ public class EurekaInstanceConfigValidator { * @throws MetadataValidationException if the validation fails */ public void validate(ApiMediationServiceConfig config) { + EurekaUtils.validateServiceId(config.getServiceId()); validateRoutes(config.getRoutes()); if (config.getDiscoveryServiceUrls().stream().anyMatch(url -> url.toLowerCase().startsWith("https"))) { validateSsl(config.getSsl());