From ca186da1c578af666ca6996bbeaed5e9d0be07a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=2E=20D=C3=A9chamboux?= Date: Fri, 14 Feb 2020 16:44:28 +0100 Subject: [PATCH] Complement tests with integration tests calling the broker API. Ensure that there cannot be duplicate instance with same instance name. --- README.md | 2 +- src/main/adminapi/SecurityAuthorities.java | 49 ++++++++ .../ApplicationConfiguration.java | 2 +- ...guration.java => BrokerConfiguration.java} | 3 +- .../MatomoServiceInstanceService.java | 29 ++--- .../repository/PMatomoInstanceRepository.java | 1 + .../McfsAuthenticationEntryPoint.java | 38 +++--- .../McfsSecurityConfigurerAdapter.java | 12 +- .../web/security/SecurityConfig.java | 29 ++--- .../web/service/MatomoInstanceService.java | 56 ++++----- .../oss/matomocfservice/TestIntegBroker.java | 117 +++++++++++++----- .../cfmgr/CfMgr4TResponseMask.java | 9 ++ .../cfmgr/CloudFoundryMgr4Test.java | 4 +- src/test/resources/application.yml | 2 +- 14 files changed, 231 insertions(+), 122 deletions(-) create mode 100644 src/main/adminapi/SecurityAuthorities.java rename src/main/java/com/orange/oss/matomocfservice/servicebroker/{BrokerApiVersionConfiguration.java => BrokerConfiguration.java} (92%) diff --git a/README.md b/README.md index 66a5a7d..5bccf1a 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ In order to produce your configured service package, do the following: It produces a jar file which contains the whole code for the service as well as the releases of Matomo to be proposed for service instantiation. -If you want to run unit tests for your configuration, there are three things you not to know or do: +If you want to run unit tests for your configuration, there are three things you need to know or to do: 1. The tests expect that you have configured your service with only one Matomo release. diff --git a/src/main/adminapi/SecurityAuthorities.java b/src/main/adminapi/SecurityAuthorities.java new file mode 100644 index 0000000..7662576 --- /dev/null +++ b/src/main/adminapi/SecurityAuthorities.java @@ -0,0 +1,49 @@ +/** + * Copyright 2020 Orange and the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.orange.oss.matomocfservice.security; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; + +/** + * @author P. Déchamboux + * + */ +@Configuration +public class SecurityAuthorities { + private final static Logger LOGGER = LoggerFactory.getLogger(SecurityAuthorities.class); + public static final String ROLE_ADMIN = "ADMIN"; + public static final String ROLE_BROKER_USER = "BROKER_USER"; + public static final String ROLE_FULL_ACCESS = "FULL_ACCESS"; + public static final String ROLE_READ_ONLY = "READ_ONLY"; + @Value("${matomo-service.security.adminName}") + private String adminName; + @Value("${matomo-service.security.adminPassword}") + private String adminPassword; + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + LOGGER.debug("CONFIG::security: configureGlobal"); + auth.inMemoryAuthentication() + .withUser(adminName) + .password(/*"{noop}" + */adminPassword) + .roles(ROLE_ADMIN, ROLE_BROKER_USER); + } +} diff --git a/src/main/java/com/orange/oss/matomocfservice/ApplicationConfiguration.java b/src/main/java/com/orange/oss/matomocfservice/ApplicationConfiguration.java index 6a778fd..0ccacb7 100755 --- a/src/main/java/com/orange/oss/matomocfservice/ApplicationConfiguration.java +++ b/src/main/java/com/orange/oss/matomocfservice/ApplicationConfiguration.java @@ -96,7 +96,7 @@ public ApplicationInformation defaultApplicationInformation() { @EventListener(ApplicationReadyEvent.class) public void initializeAfterStartup() { - LOGGER.debug("CONFIG - run initialization code after application startup has completed"); + LOGGER.debug("CONFIG::ApplicationConfiguration - run initialization code after application startup has completed"); matomoReleases.initialize(); cfMgr.initialize(); instanceIdMgr.initialize(); diff --git a/src/main/java/com/orange/oss/matomocfservice/servicebroker/BrokerApiVersionConfiguration.java b/src/main/java/com/orange/oss/matomocfservice/servicebroker/BrokerConfiguration.java similarity index 92% rename from src/main/java/com/orange/oss/matomocfservice/servicebroker/BrokerApiVersionConfiguration.java rename to src/main/java/com/orange/oss/matomocfservice/servicebroker/BrokerConfiguration.java index 0e7d76c..48333b0 100755 --- a/src/main/java/com/orange/oss/matomocfservice/servicebroker/BrokerApiVersionConfiguration.java +++ b/src/main/java/com/orange/oss/matomocfservice/servicebroker/BrokerConfiguration.java @@ -25,7 +25,8 @@ * */ @Configuration -public class BrokerApiVersionConfiguration { +public class BrokerConfiguration { + @Bean public BrokerApiVersion brokerApiVersion() { return new BrokerApiVersion(); diff --git a/src/main/java/com/orange/oss/matomocfservice/servicebroker/MatomoServiceInstanceService.java b/src/main/java/com/orange/oss/matomocfservice/servicebroker/MatomoServiceInstanceService.java index d2df8e7..d815fbf 100755 --- a/src/main/java/com/orange/oss/matomocfservice/servicebroker/MatomoServiceInstanceService.java +++ b/src/main/java/com/orange/oss/matomocfservice/servicebroker/MatomoServiceInstanceService.java @@ -23,7 +23,6 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.servicebroker.exception.ServiceInstanceDoesNotExistException; -import org.springframework.cloud.servicebroker.exception.ServiceInstanceExistsException; import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest; import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse; import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceRequest; @@ -80,6 +79,7 @@ private String getPlatformId(String platformId) { public Mono createServiceInstance(CreateServiceInstanceRequest request) { LOGGER.debug("BROKER::createServiceInstance: platformId={}, serviceId={}", request.getPlatformInstanceId(), request.getServiceInstanceId()); LOGGER.debug("BROKER:: platform={}, serviceDefId={}", request.getContext().getPlatform(), request.getServiceDefinitionId()); + LOGGER.debug("REQUEST={}", request); PMatomoInstance.PlatformKind pfkind; String instname; switch (request.getContext().getPlatform()) { @@ -92,6 +92,7 @@ public Mono createServiceInstance(CreateServiceIn pfkind = PMatomoInstance.PlatformKind.OTHER; instname = ""; } + LOGGER.debug("BROKER:: instanceName={}", instname); String errmsg = miServ.createMatomoInstance( request.getServiceInstanceId(), instname, @@ -166,15 +167,6 @@ public Mono deleteServiceInstance(DeleteServiceIn @Override public Mono updateServiceInstance(UpdateServiceInstanceRequest request) { LOGGER.debug("BROKER::updateServiceInstance: platformId={}, instanceId={}", request.getPlatformInstanceId(), request.getServiceInstanceId()); - String instn; - switch (request.getContext().getPlatform()) { - case "cloudfoundry": - instn = (String)request.getContext().getProperty("instance_name"); - break; - default: - LOGGER.warn("BROKER:: unknown kind of platform -> " + request.getContext().getPlatform()); - instn = ""; - } String emsg = miServ.updateMatomoInstance( request.getServiceInstanceId(), getPlatformId(request.getPlatformInstanceId()), @@ -219,7 +211,7 @@ private String getVersion(Map parameters) { instversion = matomoReleases.getLatestReleaseName(); } else if (! matomoReleases.isVersionAvailable(instversion)) { LOGGER.warn("SERV::getVersion: version {} is not supported -> switch to default one.", instversion); - throw new RuntimeException("Version <" + instversion + "> is not supported by this Matomo CF Service!!"); + instversion = matomoReleases.getDefaultReleaseName(); } LOGGER.debug("SERV::getVersion: {}", instversion); return instversion; @@ -254,13 +246,16 @@ private int getInstances(Map parameters, String planid) { if (planid.equals(ServiceCatalogConfiguration.PLANMATOMOSHARDB_UUID)) { instances = CLUSTERSIZE_DEFAULT; } else { - instances = (Integer) parameters.get(PARAM_INSTANCES); - if (instances == null) { - instances = CLUSTERSIZE_DEFAULT; - } else if (instances < CLUSTERSIZE_DEFAULT) { + String sinstances = (String) parameters.get(PARAM_INSTANCES); + if (sinstances == null) { instances = CLUSTERSIZE_DEFAULT; - } else if (instances > MAX_INSTANCES) { - instances = MAX_INSTANCES; + } else { + instances = Integer.decode(sinstances); + if (instances < CLUSTERSIZE_DEFAULT) { + instances = CLUSTERSIZE_DEFAULT; + } else if (instances > MAX_INSTANCES) { + instances = MAX_INSTANCES; + } } } } diff --git a/src/main/java/com/orange/oss/matomocfservice/web/repository/PMatomoInstanceRepository.java b/src/main/java/com/orange/oss/matomocfservice/web/repository/PMatomoInstanceRepository.java index b7387e6..e5075a4 100755 --- a/src/main/java/com/orange/oss/matomocfservice/web/repository/PMatomoInstanceRepository.java +++ b/src/main/java/com/orange/oss/matomocfservice/web/repository/PMatomoInstanceRepository.java @@ -32,6 +32,7 @@ @Repository public interface PMatomoInstanceRepository extends JpaRepository { Optional findByUuid(String id); + Optional findByName(String name); List findByPlatform(PPlatform pf); List findByPlatformAndLastOperation(PPlatform pf, String lastop); } diff --git a/src/main/java/com/orange/oss/matomocfservice/web/security/McfsAuthenticationEntryPoint.java b/src/main/java/com/orange/oss/matomocfservice/web/security/McfsAuthenticationEntryPoint.java index 0b45365..76dc42d 100755 --- a/src/main/java/com/orange/oss/matomocfservice/web/security/McfsAuthenticationEntryPoint.java +++ b/src/main/java/com/orange/oss/matomocfservice/web/security/McfsAuthenticationEntryPoint.java @@ -16,15 +16,8 @@ package com.orange.oss.matomocfservice.web.security; -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; /** @@ -34,13 +27,30 @@ public class McfsAuthenticationEntryPoint extends BasicAuthenticationEntryPoint { private final static Logger LOGGER = LoggerFactory.getLogger(McfsAuthenticationEntryPoint.class); - @Override - public void commence(HttpServletRequest request, - HttpServletResponse response, - AuthenticationException authException) throws IOException, ServletException { - LOGGER.debug("SECU:: authent entry point"); - response.sendRedirect(request.getContextPath() + "/login"); - } +// @Override +// public void commence(HttpServletRequest request, +// HttpServletResponse response, +// AuthenticationException authException) throws IOException, ServletException { +// LOGGER.debug("SECU:: authent entry point: {}", request.toString()); +// LOGGER.debug("AuthType: {}", request.getAuthType()); +// LOGGER.debug("ContextPath: {}", request.getContextPath()); +// LOGGER.debug("CharacterEncoding: {}", request.getCharacterEncoding()); +// LOGGER.debug("LocalAddr: {}", request.getLocalAddr()); +// LOGGER.debug("LocalName: {}", request.getLocalName()); +// LOGGER.debug("LocalPort: {}", request.getLocalPort()); +// LOGGER.debug("Method: {}", request.getMethod()); +// Enumeration headerNames = request.getHeaderNames(); +// while(headerNames.hasMoreElements()) { +// String headerName = headerNames.nextElement(); +// LOGGER.debug(" Header Name - {}, Value - {}", headerName, request.getHeader(headerName)); +// } +// Enumeration params = request.getParameterNames(); +// while(params.hasMoreElements()){ +// String paramName = params.nextElement(); +// LOGGER.debug(" Parameter Name - {}, Value - {}", paramName, request.getParameter(paramName)); +// } +// response.sendRedirect(request.getContextPath() + "/login"); +// } @Override public void afterPropertiesSet() throws Exception { diff --git a/src/main/java/com/orange/oss/matomocfservice/web/security/McfsSecurityConfigurerAdapter.java b/src/main/java/com/orange/oss/matomocfservice/web/security/McfsSecurityConfigurerAdapter.java index 1487af1..1458a61 100755 --- a/src/main/java/com/orange/oss/matomocfservice/web/security/McfsSecurityConfigurerAdapter.java +++ b/src/main/java/com/orange/oss/matomocfservice/web/security/McfsSecurityConfigurerAdapter.java @@ -26,8 +26,6 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import com.orange.oss.matomocfservice.web.security.SecurityConfig.McfsLogoutSuccessHandler; - /** * @author P. Déchamboux * @@ -48,11 +46,11 @@ protected void configure(HttpSecurity http) throws Exception { // .anyRequest().hasRole(SecurityConfig.ROLE_ADMIN) .and().httpBasic() .realmName(SecurityConfig.REALM_NAME).authenticationEntryPoint(new McfsAuthenticationEntryPoint()) - .and().formLogin() - .successHandler(new McfsAuthenticationSuccessHandler(adminSessionTimeout)) - .and().logout().permitAll() - .logoutSuccessHandler(new McfsLogoutSuccessHandler()) - .invalidateHttpSession(true) +// .and().formLogin() +// .successHandler(new McfsAuthenticationSuccessHandler(adminSessionTimeout)) +// .and().logout().permitAll() +// .logoutSuccessHandler(new McfsLogoutSuccessHandler()) +// .invalidateHttpSession(true) .and().csrf().disable(); http.sessionManagement().maximumSessions(SecurityConfig.MAX_SESSIONS).expiredUrl("/login?expired=true"); } diff --git a/src/main/java/com/orange/oss/matomocfservice/web/security/SecurityConfig.java b/src/main/java/com/orange/oss/matomocfservice/web/security/SecurityConfig.java index 075dc64..d666752 100755 --- a/src/main/java/com/orange/oss/matomocfservice/web/security/SecurityConfig.java +++ b/src/main/java/com/orange/oss/matomocfservice/web/security/SecurityConfig.java @@ -16,12 +16,7 @@ package com.orange.oss.matomocfservice.web.security; -import java.io.IOException; - import javax.annotation.PostConstruct; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,8 +26,6 @@ import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; /** * @author P. Déchamboux @@ -60,17 +53,17 @@ public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception .roles(ROLE_ADMIN); } - public static class McfsLogoutSuccessHandler implements LogoutSuccessHandler { - private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); - - @Override - public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, - Authentication authentication) throws IOException, ServletException { - LOGGER.debug("CONFIG::security: logout!!"); - // Currently logout success url="/" - response.sendRedirect(request.getContextPath()); - } - } +// public static class McfsLogoutSuccessHandler implements LogoutSuccessHandler { +// private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); +// +// @Override +// public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, +// Authentication authentication) throws IOException, ServletException { +// LOGGER.debug("CONFIG::security: logout!!"); +// // Currently logout success url="/" +// response.sendRedirect(request.getContextPath()); +// } +// } @PostConstruct public void afterInitialize() { diff --git a/src/main/java/com/orange/oss/matomocfservice/web/service/MatomoInstanceService.java b/src/main/java/com/orange/oss/matomocfservice/web/service/MatomoInstanceService.java index 831a90f..4b22df7 100755 --- a/src/main/java/com/orange/oss/matomocfservice/web/service/MatomoInstanceService.java +++ b/src/main/java/com/orange/oss/matomocfservice/web/service/MatomoInstanceService.java @@ -50,7 +50,6 @@ @Service public class MatomoInstanceService extends OperationStatusService { private final static Logger LOGGER = LoggerFactory.getLogger(MatomoInstanceService.class); - private final static String NOTINSTALLED = "NOT_INST"; @Autowired private PMatomoInstanceRepository miRepo; @Autowired @@ -119,12 +118,10 @@ public String getInstanceUrl(String mi_uuid) { public String createMatomoInstance(String uuid, String instname, PlatformKind pfkind, String apiinfolocation, String planid, String pfid, Parameters parameters) { Assert.notNull(uuid, "instance uuid mustn't be null"); + Assert.notNull(instname, "instance name mustn't be null"); Assert.notNull(pfkind, "platform kind mustn't be null"); Assert.notNull(planid, "planid mustn't be null"); Assert.notNull(parameters, "parameters mustn't be null"); - if (instname == null) { - instname = "none"; - } if (apiinfolocation == null) { apiinfolocation = ""; } @@ -134,23 +131,30 @@ public String createMatomoInstance(String uuid, String instname, PlatformKind pf LOGGER.error("Cannot create any kind of instance: service unavailable (retry later on)"); return "Cannot create any kind of instance: service unavailable (retry later on)"; } - EntityManager em = beginTx(); PMatomoInstance pmi; - try { - if (getMatomoInstance(uuid, pfid) != null) { - LOGGER.error("Matomo Instance with ID=" + uuid + " already exists in Platform with ID=" + pfid); - return "Matomo Instance with ID=" + uuid + " already exists in Platform with ID=" + pfid; + synchronized (this) { + EntityManager em = beginTx(); + try { + if (getMatomoInstance(uuid, pfid) != null) { + LOGGER.error("Matomo Instance with ID=" + uuid + " already exists in Platform with ID=" + pfid); + return "Matomo Instance with ID=" + uuid + " already exists in Platform with ID=" + pfid; + } + if (miRepo.findByName(instname).isPresent()) { + LOGGER.error( + "Matomo Instance with name=" + instname + " already exists in Platform with ID=" + pfid); + return "Matomo Instance with name=" + instname + " already exists in Platform with ID=" + pfid; + } + PPlatform ppf = getPPlatform(pfid); + pmi = new PMatomoInstance(uuid, instanceIdMgr.allocateInstanceId(), instname, pfkind, apiinfolocation, + planid, ppf, parameters); + savePMatomoInstance(pmi, OperationState.IN_PROGRESS); + } catch (Exception e) { + return "Error while initializing creation: " + e.getMessage(); + } finally { + commitTx(em); } - PPlatform ppf = getPPlatform(pfid); - pmi = new PMatomoInstance(uuid, instanceIdMgr.allocateInstanceId(), instname, pfkind, - apiinfolocation, planid, ppf, parameters); - savePMatomoInstance(pmi, OperationState.IN_PROGRESS); - matomoReleases.createLinkedTree(parameters.getVersion(), pmi.getIdUrlStr()); - } catch (Exception e) { - return "Error while initializing creation: " + e.getMessage(); - } finally { - commitTx(em); } + matomoReleases.createLinkedTree(parameters.getVersion(), pmi.getIdUrlStr()); Mono createdb = (properties.getDbCreds(planid).isDedicatedDb()) ? cfMgr.createDedicatedDb(pmi.getIdUrlStr(), planid) : Mono.empty(); @@ -245,16 +249,11 @@ public String deleteMatomoInstance(String uuid, String platformId) { } pmi.setLastOperation(POperationStatus.OpCode.DELETE_SERVICE_INSTANCE); savePMatomoInstance(pmi, OperationState.IN_PROGRESS); - if (pmi.getInstalledVersion().equals(NOTINSTALLED)) { - savePMatomoInstance(pmi, OperationState.SUCCEEDED); - instanceIdMgr.freeInstanceId(pmi.getIdUrl()); - pmi.setConfigFileContent(null); - return "Nothing to delete for instance with ID=" + pmi.getUuid(); - } // delete data associated with the instance under deletion cfMgr.deleteAssociatedDbSchema(pmi); } catch (Exception e) { - throw e; + LOGGER.warn("SERV::deleteMatomoInstance: KO -> Exception: " + e.getMessage()); + return null; } finally { commitTx(em); } @@ -328,11 +327,6 @@ public String updateMatomoInstance(String uuid, String pfid, Parameters paramete } pmi.setLastOperation(POperationStatus.OpCode.UPDATE_SERVICE_INSTANCE); savePMatomoInstance(pmi, OperationState.IN_PROGRESS); - if (pmi.getInstalledVersion().equals(NOTINSTALLED)) { - LOGGER.warn("Nothing to update (not installed) for instance with ID=" + pmi.getUuid()); - savePMatomoInstance(pmi, OperationState.SUCCEEDED).getUuid(); - return null; - } if (pmi.getAutomaticVersionUpgrade() != parameters.isAutoVersionUpgrade()) { pmi.setAutomaticVersionUpgrade(parameters.isAutoVersionUpgrade()); savePMatomoInstance(pmi, null); @@ -362,7 +356,7 @@ public String updateMatomoInstance(String uuid, String pfid, Parameters paramete savePMatomoInstance(pmi, null); } } catch (Exception e) { - return ""; + return "KO -> Exception: " + e.getMessage(); } finally { commitTx(em); } diff --git a/src/test/java/com/orange/oss/matomocfservice/TestIntegBroker.java b/src/test/java/com/orange/oss/matomocfservice/TestIntegBroker.java index 0629093..bc126c2 100644 --- a/src/test/java/com/orange/oss/matomocfservice/TestIntegBroker.java +++ b/src/test/java/com/orange/oss/matomocfservice/TestIntegBroker.java @@ -18,12 +18,9 @@ import static io.restassured.RestAssured.given; import java.net.URI; -import java.net.URISyntaxException; import java.util.UUID; -import org.json.JSONException; import org.json.JSONObject; -import org.junit.Assert; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -32,7 +29,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import com.orange.oss.matomocfservice.cfmgr.CfMgr4TResponseMask; @@ -89,23 +85,34 @@ static class Catalog { } } - private String createBody(String planid, String param_version) { + private String createBody(String instname, String planid, String param_version, int nbinst) { StringBuffer sb = new StringBuffer("{\"service_id\": \""); sb.append(catalog.id); sb.append("\", \"plan_id\": \""); sb.append(planid); sb.append("\", \"context\": {\"platform\": \"cloudfoundry\""); sb.append(", \"api_info_location\": \"https://api.cloudfoundry.mycompany\""); + sb.append(", \"instance_name\": \""); + sb.append(instname); + sb.append("\""); sb.append(", \"organization_guid\": \"myorg\""); sb.append(", \"space_guid\": \"myspace\""); // other context fields below //sb.append(", \"\": \"\""); sb.append("}, \"parameters\": {"); // parameters below + String comma = ""; if (param_version == null) { - sb.append("\"version\": \""); + sb.append("\"matomoVersion\": \""); sb.append(param_version); sb.append("\""); + comma = ", "; + } + if (nbinst == -1) { + sb.append(comma); + sb.append("\"matomoInstances\": \""); + sb.append(nbinst); + sb.append("\""); } //sb.append("\"\": \"\""); sb.append("}, \"maintenance_info\": {"); @@ -214,7 +221,7 @@ void testCreateInstanceGlobShared() { Response resp = given() .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, null)). + .body(createBody("M01", catalog.plans[GLOBAL_SHARED_DB].id, null, -1)). when() .put(createServiceInstUri(instid, null, null)). then() @@ -233,8 +240,7 @@ void testCreateInstanceGlobShared() { .response(); Assertions.assertEquals("succeeded", resp.getBody().jsonPath().getString("state")); resp = given() - .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, null)). + .header("Content-Type", "application/json"). when() .delete(createServiceInstUri(instid, catalog.id, catalog.plans[GLOBAL_SHARED_DB].id)). then() @@ -262,7 +268,7 @@ void testGetInstanceGlobShared() { Response resp = given() .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, null)). + .body(createBody("M02", catalog.plans[GLOBAL_SHARED_DB].id, null, -1)). when() .put(createServiceInstUri(instid, null, null)). then() @@ -281,8 +287,7 @@ void testGetInstanceGlobShared() { .response(); Assertions.assertEquals("succeeded", resp.getBody().jsonPath().getString("state")); resp = given() - .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, null)). + .header("Content-Type", "application/json"). when() .get(createServiceInstUri(instid, null, null)). then() @@ -293,8 +298,7 @@ void testGetInstanceGlobShared() { Assertions.assertEquals(catalog.id, resp.getBody().jsonPath().getString("service_id")); Assertions.assertEquals(catalog.plans[GLOBAL_SHARED_DB].id, resp.getBody().jsonPath().getString("plan_id")); resp = given() - .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, null)). + .header("Content-Type", "application/json"). when() .delete(createServiceInstUri(instid, catalog.id, catalog.plans[GLOBAL_SHARED_DB].id)). then() @@ -314,15 +318,34 @@ void testGetInstanceGlobShared() { Assertions.assertEquals("succeeded", resp.getBody().jsonPath().getString("state")); } + @Test + void testGetInstanceGlobSharedKONotExist() { + LOGGER.debug("testGetInstanceGlobSharedKONotExist"); + String instid = UUID.randomUUID().toString(); + cfMgr4T.setResponseMask(new CfMgr4TResponseMask()); + Response resp = given() + .header("Content-Type", "application/json") + .body(createBody("M04", catalog.plans[GLOBAL_SHARED_DB].id, null, -1)). + when() + .get(createServiceInstUri(instid, null, null)). + then() + .statusCode(200) + .contentType(ContentType.JSON) + .extract() + .response(); + Assertions.assertEquals("", resp.getBody().jsonPath().getString("service_id")); + Assertions.assertEquals("", resp.getBody().jsonPath().getString("plan_id")); + } + @Test void testUpdateInstanceGlobShared() { - LOGGER.debug("testGetInstanceGlobShared"); + LOGGER.debug("testUpdateInstanceGlobShared"); String instid = UUID.randomUUID().toString(); cfMgr4T.setResponseMask(new CfMgr4TResponseMask()); Response resp = given() .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, null)). + .body(createBody("M05", catalog.plans[GLOBAL_SHARED_DB].id, null, -1)). when() .put(createServiceInstUri(instid, null, null)). then() @@ -342,7 +365,7 @@ void testUpdateInstanceGlobShared() { Assertions.assertEquals("succeeded", resp.getBody().jsonPath().getString("state")); resp = given() .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, "3.45.0")). + .body(createBody("M06", catalog.plans[GLOBAL_SHARED_DB].id, "3.45.0", -1)). when() .patch(createServiceInstUri(instid, null, null)). then() @@ -352,8 +375,7 @@ void testUpdateInstanceGlobShared() { .response(); LOGGER.debug("Resp: {}", resp.prettyPrint()); resp = given() - .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, null)). + .header("Content-Type", "application/json"). when() .delete(createServiceInstUri(instid, catalog.id, catalog.plans[GLOBAL_SHARED_DB].id)). then() @@ -374,14 +396,14 @@ void testUpdateInstanceGlobShared() { } @Test - void testCreateInstanceGlobSharedKO() { - LOGGER.debug("testCreateInstanceGlobSharedKO"); + void testCreateInstanceGlobSharedKOGSDBNotReady() { + LOGGER.debug("testCreateInstanceGlobSharedKOGSDBNotReady"); String instid = UUID.randomUUID().toString(); cfMgr4T.setResponseMask(new CfMgr4TResponseMask().globalSharedReady(false)); Response resp = given() .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, null)). + .body(createBody("M07", catalog.plans[GLOBAL_SHARED_DB].id, null, -1)). when() .put(createServiceInstUri(instid, null, null)). then() @@ -400,14 +422,51 @@ void testCreateInstanceGlobSharedKO() { .response(); Assertions.assertEquals("failed", resp.getBody().jsonPath().getString("state")); given() - .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, null)). + .header("Content-Type", "application/json"). when() .delete(createServiceInstUri(instid, catalog.id, catalog.plans[GLOBAL_SHARED_DB].id)). then() .statusCode(410); } + @Test + void testCreateInstanceGlobSharedKODupInstname() { + LOGGER.debug("testCreateInstanceGlobSharedKODupInstname"); + String instid = UUID.randomUUID().toString(); + cfMgr4T.setResponseMask(new CfMgr4TResponseMask()); + Response resp = + given() + .header("Content-Type", "application/json") + .body(createBody("M08", catalog.plans[GLOBAL_SHARED_DB].id, null, -1)). + when() + .put(createServiceInstUri(instid, null, null)). + then() + .statusCode(202) + .contentType(ContentType.JSON) + .extract() + .response(); + resp = given() + .header("Content-Type", "application/json") + .body(createBody("M08", catalog.plans[GLOBAL_SHARED_DB].id, null, -1)). + when() + .put(createServiceInstUri(UUID.randomUUID().toString(), null, null)). + then() + .statusCode(202) + .contentType(ContentType.JSON) + .extract() + .response(); + Assertions.assertTrue(resp.getBody().jsonPath().getString("operation").startsWith("Matomo Instance with name=")); + resp = given() + .header("Content-Type", "application/json"). + when() + .delete(createServiceInstUri(instid, catalog.id, catalog.plans[GLOBAL_SHARED_DB].id)). + then() + .statusCode(202) + .contentType(ContentType.JSON) + .extract() + .response(); + } + @Test void testCreateInstanceMatomoShared() { LOGGER.debug("testCreateInstanceMatomoShared"); @@ -416,7 +475,7 @@ void testCreateInstanceMatomoShared() { Response resp = given() .header("Content-Type", "application/json") - .body(createBody(catalog.plans[MATOMO_SHARED_DB].id, null)). + .body(createBody("M09", catalog.plans[MATOMO_SHARED_DB].id, null, -1)). when() .put(createServiceInstUri(instid, null, null)). then() @@ -435,8 +494,7 @@ void testCreateInstanceMatomoShared() { .response(); Assertions.assertEquals("succeeded", resp.getBody().jsonPath().getString("state")); resp = given() - .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, null)). + .header("Content-Type", "application/json"). when() .delete(createServiceInstUri(instid, catalog.id, catalog.plans[GLOBAL_SHARED_DB].id)). then() @@ -464,7 +522,7 @@ void testCreateInstanceDedicated() { Response resp = given() .header("Content-Type", "application/json") - .body(createBody(catalog.plans[DEDICTED_DB].id, null)). + .body(createBody("M10", catalog.plans[DEDICTED_DB].id, null, -1)). when() .put(createServiceInstUri(instid, null, null)). then() @@ -483,8 +541,7 @@ void testCreateInstanceDedicated() { .response(); Assertions.assertEquals("succeeded", resp.getBody().jsonPath().getString("state")); resp = given() - .header("Content-Type", "application/json") - .body(createBody(catalog.plans[GLOBAL_SHARED_DB].id, null)). + .header("Content-Type", "application/json"). when() .delete(createServiceInstUri(instid, catalog.id, catalog.plans[GLOBAL_SHARED_DB].id)). then() diff --git a/src/test/java/com/orange/oss/matomocfservice/cfmgr/CfMgr4TResponseMask.java b/src/test/java/com/orange/oss/matomocfservice/cfmgr/CfMgr4TResponseMask.java index b890efd..06d516c 100644 --- a/src/test/java/com/orange/oss/matomocfservice/cfmgr/CfMgr4TResponseMask.java +++ b/src/test/java/com/orange/oss/matomocfservice/cfmgr/CfMgr4TResponseMask.java @@ -31,6 +31,7 @@ public class CfMgr4TResponseMask { private int delayDeployCfApp = 0; private int failedDeployCfAppAtOccur = 0; private int deployCfAppOccur = 0; + private boolean failedScaleMatomoCfApp = false; private boolean failedGetConfFile = false; private boolean failedGetAppEnv = false; private boolean failedGetApiAccessToken = false; @@ -126,6 +127,14 @@ public int delayDeployCfApp() { return delayDeployCfApp; } + public CfMgr4TResponseMask setFailedScaleMatomoCfApp() { + failedScaleMatomoCfApp = true; + return this; + } + public boolean failedScaleMatomoCfApp() { + return failedGetConfFile; + } + public CfMgr4TResponseMask setFailedGetConfFile() { failedGetConfFile = true; return this; diff --git a/src/test/java/com/orange/oss/matomocfservice/cfmgr/CloudFoundryMgr4Test.java b/src/test/java/com/orange/oss/matomocfservice/cfmgr/CloudFoundryMgr4Test.java index 65318d3..0f2e623 100755 --- a/src/test/java/com/orange/oss/matomocfservice/cfmgr/CloudFoundryMgr4Test.java +++ b/src/test/java/com/orange/oss/matomocfservice/cfmgr/CloudFoundryMgr4Test.java @@ -21,7 +21,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.slf4j.Logger; @@ -94,6 +93,9 @@ public Mono deployMatomoCfApp(String instid, String uuid, String planid, P @Override public Mono scaleMatomoCfApp(String instid, int instances, int memsize) { LOGGER.debug("CFMGR-TEST::scaleMatomoCfApp: instId={}, instances={}, memsize={}", instid, instances, memsize); + if (respMask.failedScaleMatomoCfApp()) { + return Mono.error(new TimeoutException("Timeout after some time")); + } return Mono.create(sink -> {sink.success();}); } diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 3aa0751..4cdef50 100755 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -1,7 +1,7 @@ debug: false test: - currentRelease: 3.13.1 + currentRelease: 3.13.2 lowerReleaseNotAvailable: 3.6.1 logging: