├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── activity-tracker-root ├── activity-tracker-boot-starter │ └── src │ │ ├── main │ │ ├── java │ │ │ └── io │ │ │ │ └── fourfinance │ │ │ │ └── activity_tracker │ │ │ │ └── autoconfigure │ │ │ │ └── ActivityTrackerAutoConfiguration.java │ │ └── resources │ │ │ └── META-INF │ │ │ └── spring.factories │ │ └── test │ │ └── java │ │ └── io │ │ └── fourfinance │ │ └── activity_tracker │ │ ├── autoconfigure │ │ ├── ActivityTrackerAutoConfigurationDisabledTest.java │ │ └── ActivityTrackerAutoConfigurationEnabledTest.java │ │ └── testapp │ │ └── TestApplication.java ├── activity-tracker │ └── src │ │ ├── main │ │ └── java │ │ │ └── io │ │ │ └── fourfinance │ │ │ └── activity_tracker │ │ │ ├── activity │ │ │ ├── ActivityParameters.java │ │ │ ├── DefaultTrackUserActivityMetrics.java │ │ │ ├── JoinPointParameters.java │ │ │ ├── TrackUserActivity.java │ │ │ ├── TrackUserActivityAspect.java │ │ │ └── TrackUserActivityMetrics.java │ │ │ └── audit │ │ │ ├── DefaultTrackUserActivityAudits.java │ │ │ └── TrackUserActivityAudits.java │ │ └── test │ │ └── groovy │ │ └── io │ │ └── fourfinance │ │ └── activity_tracker │ │ └── activity │ │ └── TrackUserActivityAspectSpec.groovy └── build.gradle ├── build.gradle ├── gradle.properties ├── gradle ├── github.gradle ├── publish.gradle ├── release.gradle ├── runBootMicroserviceAcceptanceTests.sh ├── setGitVariables.sh ├── version.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── micro-deps ├── build.gradle ├── micro-deps-jax-rs-jersey │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── ofg │ │ │ └── infrastructure │ │ │ └── jaxrs │ │ │ ├── JaxRsServiceResolver.java │ │ │ └── JerseyServiceResolver.java │ │ └── test │ │ └── java │ │ └── com │ │ └── ofg │ │ └── infrastructure │ │ ├── jaxrs │ │ └── JaxRsApi.java │ │ └── jerseys │ │ ├── JerseyApplication.java │ │ ├── JerseyConfig.java │ │ ├── JerseyResource.java │ │ └── JerseyTest.java ├── micro-deps-spring-config │ ├── README.md │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── ofg │ │ │ │ ├── config │ │ │ │ ├── BasicProfiles.java │ │ │ │ └── NotSpringCloudProfile.java │ │ │ │ └── infrastructure │ │ │ │ └── discovery │ │ │ │ ├── AddressProviderConfiguration.java │ │ │ │ ├── ConsumerDrivenContractConfiguration.java │ │ │ │ ├── DependencyResolutionConfiguration.java │ │ │ │ ├── MicroserviceAddressProvider.java │ │ │ │ ├── MicroserviceJsonConfiguration.java │ │ │ │ ├── ServiceDiscoveryInfrastructureConfiguration.java │ │ │ │ ├── ServiceResolverConfiguration.java │ │ │ │ ├── SpringCloudToMicroserviceJsonConverter.java │ │ │ │ ├── SpringCloudZookeeperConfiguration.java │ │ │ │ ├── SpringCloudZookeeperConnectorConfiguration.java │ │ │ │ ├── SpringCloudZookeeperServiceResolver.java │ │ │ │ ├── ZookeeperConnector.java │ │ │ │ ├── ZookeeperConnectorConditions.java │ │ │ │ └── ZookeeperServiceResolverConfiguration.java │ │ └── resources │ │ │ └── application-test.yaml │ │ └── test │ │ ├── groovy │ │ └── com │ │ │ └── ofg │ │ │ └── infrastructure │ │ │ └── discovery │ │ │ ├── ApplicationContextStartupSpec.groovy │ │ │ ├── ConsumerDrivenContractSpec.groovy │ │ │ ├── ServiceResolverConfigurationSpec.groovy │ │ │ ├── ServiceResolverSpec.groovy │ │ │ ├── SpringCloudToMicroserviceJsonConverterSpec.groovy │ │ │ ├── ZookeeperConnectorConditionsSpec.groovy │ │ │ └── config │ │ │ ├── ConfigWithEnvironment.groovy │ │ │ └── PropertySourceConfiguration.groovy │ │ └── resources │ │ ├── logback-test.groovy │ │ ├── microservice.properties │ │ └── stub-microservice.json ├── micro-deps-spring-test-config │ ├── README.md │ └── src │ │ ├── main │ │ └── groovy │ │ │ └── com │ │ │ └── ofg │ │ │ └── infrastructure │ │ │ ├── base │ │ │ ├── IntegrationSpec.groovy │ │ │ ├── IntegrationTest.groovy │ │ │ ├── MvcIntegrationSpec.groovy │ │ │ ├── MvcIntegrationTest.groovy │ │ │ ├── MvcWiremockIntegrationSpec.groovy │ │ │ ├── MvcWiremockIntegrationTest.groovy │ │ │ └── dsl │ │ │ │ ├── Matchers.groovy │ │ │ │ ├── StubbedHttpResponseBuilder.groovy │ │ │ │ └── WireMockHttpRequestMapper.groovy │ │ │ ├── discovery │ │ │ └── web │ │ │ │ ├── HttpMockServer.groovy │ │ │ │ └── MockServerConfiguration.groovy │ │ │ └── stub │ │ │ ├── Stub.groovy │ │ │ ├── StubConfiguration.groovy │ │ │ └── Stubs.groovy │ │ └── test │ │ ├── groovy │ │ └── com │ │ │ └── ofg │ │ │ └── infrastructure │ │ │ ├── BaseConfiguration.groovy │ │ │ ├── base │ │ │ ├── CollaboratorStubIntegrationSpec.groovy │ │ │ ├── CollaboratorStubIntegrationTest.groovy │ │ │ ├── ServiceDiscoveryWiremockIntegrationSpec.groovy │ │ │ └── ServiceDiscoveryWiremockIntegrationTest.groovy │ │ │ └── stub │ │ │ └── StubSpec.groovy │ │ └── resources │ │ ├── application-test.properties │ │ └── test-microservice.json └── micro-deps │ ├── README.md │ └── src │ ├── main │ └── java │ │ └── com │ │ └── ofg │ │ └── infrastructure │ │ └── discovery │ │ ├── IgnorePayloadInstanceSerializer.java │ │ ├── InvalidMicroserviceConfigurationException.java │ │ ├── JsonToMicroserviceConfigurationConverter.java │ │ ├── MicroserviceConfiguration.java │ │ ├── MicroserviceConfigurationNotPresentException.java │ │ ├── MicroserviceConfigurationToJsonConverter.java │ │ ├── ServiceAlias.java │ │ ├── ServiceConfigurationProperties.java │ │ ├── ServiceConfigurationResolver.java │ │ ├── ServiceConfigurationValidator.java │ │ ├── ServicePath.java │ │ ├── ServiceResolver.java │ │ ├── ServiceUnavailableException.java │ │ ├── StubbedServiceResolver.java │ │ ├── ZookeeperServiceResolver.java │ │ ├── util │ │ ├── CollectionUtils.java │ │ ├── DependencyCreator.java │ │ ├── LoadBalancerType.java │ │ ├── MicroDepsService.java │ │ └── ProviderStrategyFactory.java │ │ └── watcher │ │ ├── DependencyState.java │ │ ├── DependencyStateChangeListenerRegistry.java │ │ ├── DependencyWatcher.java │ │ ├── DependencyWatcherListener.java │ │ └── presence │ │ ├── DefaultDependencyPresenceOnStartupVerifier.java │ │ ├── DependencyPresenceOnStartupVerifier.java │ │ └── checker │ │ ├── FailOnMissingDependencyChecker.java │ │ ├── LogMissingDependencyChecker.java │ │ ├── NoInstancesRunningException.java │ │ └── PresenceChecker.java │ └── test │ └── groovy │ └── com │ └── ofg │ └── infrastructure │ ├── base │ └── SpecWithZookeper.groovy │ └── discovery │ ├── IgnorePayloadInstanceSerializerSpec.groovy │ ├── MicroDepsServiceSpec.groovy │ ├── MicroserviceConfigurationToJsonConverterSpec.groovy │ ├── MicroserviceConfigurationUtil.groovy │ ├── ServiceConfigurationResolverSpec.groovy │ ├── ServicePathSpec.groovy │ ├── ServiceResolverSpec.groovy │ ├── StubsConfigurationSpec.groovy │ ├── util │ ├── CollectionUtilsSpec.groovy │ ├── LoadBalancerTypeSpec.groovy │ └── ProviderStrategyFactorySpec.groovy │ └── watcher │ └── presence │ ├── DefaultDependencyPresenceOnStartupVerifierSpec.groovy │ └── DependencyPresenceOnStartupVerifierSpec.groovy ├── micro-infra-camel ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── ofg │ │ └── infrastructure │ │ └── camel │ │ ├── CorrelationIdInterceptor.java │ │ ├── CorrelationIdOnCamelRouteConfiguration.java │ │ ├── EnableCorrelationIdForCamel.java │ │ └── aspects │ │ └── CorrelationIdOnCamelRouteAspect.java │ └── test │ ├── groovy │ └── com │ │ └── ofg │ │ └── infrastructure │ │ └── camel │ │ ├── AcceptanceSpec.groovy │ │ ├── CorrelationIdInterceptorSpec.groovy │ │ └── config │ │ ├── CamelRouteAsBeanConfiguration.groovy │ │ └── TestRouteBuilder.groovy │ └── resources │ └── spring │ └── camel-context.xml ├── micro-infra-spring-base ├── build.gradle └── src │ ├── main │ ├── groovy │ │ └── com │ │ │ └── ofg │ │ │ └── infrastructure │ │ │ ├── correlationid │ │ │ └── CorrelationIdHolder.java │ │ │ ├── healthcheck │ │ │ ├── CollaboratorStatus.java │ │ │ ├── CollaboratorsConfiguration.java │ │ │ ├── CollaboratorsConnectivityController.java │ │ │ ├── CollaboratorsStatusResolver.groovy │ │ │ ├── EnableHealthCheck.java │ │ │ ├── HealthCheckConfiguration.java │ │ │ ├── MicroserviceConfigurationController.groovy │ │ │ ├── PingClient.java │ │ │ └── PingController.java │ │ │ └── web │ │ │ ├── config │ │ │ └── WebInfrastructureConfiguration.java │ │ │ ├── correlationid │ │ │ ├── CorrelationIdAspect.java │ │ │ ├── EnableCorrelationId.java │ │ │ └── HeadersSettingFilter.java │ │ │ ├── exception │ │ │ ├── BadParameterError.java │ │ │ ├── BadParametersException.java │ │ │ ├── ControllerExceptionConfiguration.java │ │ │ ├── ControllerExceptionHandler.java │ │ │ └── EnableExceptionHandler.java │ │ │ ├── logging │ │ │ ├── EnableObfuscatedLogging.java │ │ │ ├── RequestBodyLoggingContextFilter.java │ │ │ ├── RequestLoggingConfiguration.java │ │ │ ├── feign │ │ │ │ ├── FeignRequestResponseLoggingConifguration.java │ │ │ │ └── SleuthRequestIdProvider.java │ │ │ └── obfuscation │ │ │ │ ├── JsonPayloadObfuscator.groovy │ │ │ │ └── XmlPayloadObfuscator.groovy │ │ │ ├── resttemplate │ │ │ ├── RestOperationsMetricsAspect.groovy │ │ │ ├── custom │ │ │ │ ├── HttpStatusVerifier.groovy │ │ │ │ ├── InputStreamPrinter.groovy │ │ │ │ ├── LoggingResponseExtractorWrapper.groovy │ │ │ │ ├── ResponseException.groovy │ │ │ │ ├── ResponseRethrowingErrorHandler.groovy │ │ │ │ └── RestTemplate.groovy │ │ │ └── fluent │ │ │ │ ├── AbstractMethodBuilder.groovy │ │ │ │ ├── EnableServiceRestClient.java │ │ │ │ ├── HTTPAuthorizationUtils.groovy │ │ │ │ ├── ServiceRestClientConfiguration.groovy │ │ │ │ ├── ServiceRestClientConfigurationSupport.groovy │ │ │ │ ├── common │ │ │ │ ├── request │ │ │ │ │ ├── HttpMethod.groovy │ │ │ │ │ ├── ParametrizedUrlHavingWith.groovy │ │ │ │ │ └── RequestHaving.groovy │ │ │ │ └── response │ │ │ │ │ ├── executor │ │ │ │ │ ├── Executable.groovy │ │ │ │ │ ├── InvalidHttpMethodParametersException.groovy │ │ │ │ │ ├── LocationFindingExecutor.groovy │ │ │ │ │ ├── LocationReceiving.groovy │ │ │ │ │ ├── ResponseTypeRelatedRequestsExecutor.groovy │ │ │ │ │ ├── RestExecutor.groovy │ │ │ │ │ └── UrlParsingUtils.groovy │ │ │ │ │ └── receive │ │ │ │ │ ├── BodyContainingWithHeaders.groovy │ │ │ │ │ ├── BodyContainingWithQueryParameters.groovy │ │ │ │ │ ├── BodylessWithHeaders.groovy │ │ │ │ │ ├── BodylessWithQueryParameters.groovy │ │ │ │ │ ├── HeadersHaving.java │ │ │ │ │ ├── HttpEntitySending.groovy │ │ │ │ │ ├── ObjectReceiving.groovy │ │ │ │ │ ├── PredefinedHttpHeaders.groovy │ │ │ │ │ ├── QueryParametersHaving.java │ │ │ │ │ ├── ResponseEntityReceiving.groovy │ │ │ │ │ ├── ResponseExtracting.groovy │ │ │ │ │ ├── ResponseIgnoring.groovy │ │ │ │ │ └── ResponseReceiving.groovy │ │ │ │ ├── config │ │ │ │ ├── RestClientConfigurer.groovy │ │ │ │ ├── ServiceRestClientConfigurer.groovy │ │ │ │ └── ServiceRestClientConfigurerAdapter.groovy │ │ │ │ ├── delete │ │ │ │ ├── DeleteMethod.groovy │ │ │ │ ├── DeleteMethodBuilder.groovy │ │ │ │ ├── ResponseReceivingDeleteMethod.groovy │ │ │ │ └── UrlParameterizableDeleteMethod.groovy │ │ │ │ ├── get │ │ │ │ ├── GetMethod.groovy │ │ │ │ ├── GetMethodBuilder.groovy │ │ │ │ ├── ResponseReceivingGetMethod.groovy │ │ │ │ └── UrlParameterizableGetMethod.groovy │ │ │ │ ├── head │ │ │ │ ├── HeadMethod.groovy │ │ │ │ ├── HeadMethodBuilder.groovy │ │ │ │ ├── ResponseReceivingHeadMethod.groovy │ │ │ │ └── UrlParameterizableHeadMethod.groovy │ │ │ │ ├── options │ │ │ │ ├── AllowContainingWithHeaders.groovy │ │ │ │ ├── AllowHeaderReceiving.groovy │ │ │ │ ├── OptionsAllowHeaderExecutor.groovy │ │ │ │ ├── OptionsMethod.groovy │ │ │ │ ├── OptionsMethodBuilder.groovy │ │ │ │ ├── ResponseReceivingOptionsMethod.groovy │ │ │ │ └── UrlParameterizableOptionsMethod.groovy │ │ │ │ ├── post │ │ │ │ ├── DataUpdateMethodBuilder.groovy │ │ │ │ ├── PostMethod.groovy │ │ │ │ ├── PostMethodBuilder.groovy │ │ │ │ ├── RequestHavingPostMethod.groovy │ │ │ │ ├── ResponseReceivingPostMethod.groovy │ │ │ │ └── UrlParameterizablePostMethod.groovy │ │ │ │ └── put │ │ │ │ ├── PutMethod.groovy │ │ │ │ ├── PutMethodBuilder.groovy │ │ │ │ ├── RequestHavingPutMethod.groovy │ │ │ │ ├── ResponseReceivingPutMethod.groovy │ │ │ │ └── UrlParameterizablePutMethod.groovy │ │ │ └── view │ │ │ ├── EnableJSONViewResolver.java │ │ │ └── ViewConfiguration.java │ ├── java │ │ └── com │ │ │ └── ofg │ │ │ └── infrastructure │ │ │ ├── config │ │ │ ├── BaseWebAppConfiguration.java │ │ │ ├── EnableMicroservice.java │ │ │ └── PropertyAbsentOrEnabledCondition.java │ │ │ ├── discovery │ │ │ ├── EnableServiceDiscovery.java │ │ │ └── ServiceDiscoveryConfiguration.java │ │ │ ├── environment │ │ │ └── EnvironmentSetupVerifier.java │ │ │ ├── hystrix │ │ │ ├── EnableHystrixServlet.java │ │ │ ├── HystrixServletConfiguration.java │ │ │ └── IsHystrixServletEnabled.java │ │ │ ├── metrics │ │ │ ├── config │ │ │ │ ├── EnableMetrics.java │ │ │ │ ├── GraphiteFormat.java │ │ │ │ ├── IsGraphitePublishingEnabled.java │ │ │ │ └── MetricsConfiguration.java │ │ │ └── publishing │ │ │ │ ├── CsvPublisher.java │ │ │ │ ├── EnvironmentAwareMetricsBasePath.java │ │ │ │ ├── GraphitePublisher.java │ │ │ │ ├── JmxPublisher.java │ │ │ │ ├── MetricsBasePath.java │ │ │ │ ├── MetricsPublishing.java │ │ │ │ ├── OutputDirectoryDoesNotExists.java │ │ │ │ └── PublishingInterval.java │ │ │ ├── tracing │ │ │ ├── EnableTracing.java │ │ │ ├── TracingConfiguration.java │ │ │ └── TracingPropertiesEnabler.java │ │ │ └── web │ │ │ ├── WebConsts.java │ │ │ ├── logging │ │ │ ├── FeignCallObfuscatingLogger.java │ │ │ ├── HttpClientCallLogger.java │ │ │ ├── HttpControllerCallLogger.java │ │ │ ├── HttpData.java │ │ │ ├── HttpDataExtractor.java │ │ │ ├── HttpDataFactory.java │ │ │ ├── LogBuilder.java │ │ │ ├── RequestDataProvider.java │ │ │ ├── RequestIdProvider.java │ │ │ ├── RequestResponseLogger.java │ │ │ ├── config │ │ │ │ ├── LogsConfig.java │ │ │ │ └── LogsConfigElement.java │ │ │ ├── obfuscation │ │ │ │ ├── AbstractPayloadObfuscator.java │ │ │ │ ├── FieldReplacementStrategy.java │ │ │ │ ├── ObfuscationFieldStrategy.java │ │ │ │ └── PayloadObfuscationProcessor.java │ │ │ └── wrapper │ │ │ │ ├── DelegatingServletInputStream.java │ │ │ │ ├── DelegatingServletOutputStream.java │ │ │ │ ├── HttpServletRequestLoggingWrapper.java │ │ │ │ └── HttpServletResponseLoggingWrapper.java │ │ │ └── resttemplate │ │ │ └── fluent │ │ │ ├── HttpMethodBuilder.java │ │ │ ├── RegexMatchingPathElidingURIMetricNamer.java │ │ │ ├── ServiceRestClient.java │ │ │ ├── TracingInfo.java │ │ │ ├── URIMetricNamer.java │ │ │ ├── UrlUtils.java │ │ │ └── common │ │ │ └── response │ │ │ └── receive │ │ │ ├── HeadersSetting.java │ │ │ ├── ParametersSetting.java │ │ │ ├── QueryParametersSetting.java │ │ │ ├── WithHeaders.groovy │ │ │ └── WithQueryParameters.java │ └── resources │ │ ├── META-INF │ │ └── spring.factories │ │ └── static │ │ └── collaborators │ │ ├── scripts │ │ ├── app-8ebe535413.js │ │ └── vendor-90f1d4d361.js │ │ ├── styles │ │ ├── app-58b664cb54.css │ │ └── vendor-389eb5336b.css │ │ └── view.html │ └── test │ ├── groovy │ └── com │ │ └── ofg │ │ └── infrastructure │ │ ├── base │ │ ├── BaseConfiguration.groovy │ │ ├── ConfigurationWithoutServiceDiscovery.groovy │ │ ├── MicroserviceMvcWiremockSpec.groovy │ │ ├── MvcCorrelationIdSettingIntegrationSpec.groovy │ │ └── ServiceDiscoveryStubbingApplicationConfiguration.groovy │ │ ├── environment │ │ └── EnvironmentSetupVerifierSpec.groovy │ │ ├── healthcheck │ │ ├── CollaboratorsConnectivityControllerSpec.groovy │ │ ├── MicroserviceConfigurationControllerSpec.groovy │ │ ├── PingClientTest.groovy │ │ └── PingControllerMvcSpec.groovy │ │ ├── hystrix │ │ └── CircuitBreakers.groovy │ │ ├── metrics │ │ ├── config │ │ │ ├── GraphitePublisherRegistrationSpec.groovy │ │ │ └── GraphiteServiceConfig.groovy │ │ └── publishing │ │ │ ├── CsvPublisherSpec.groovy │ │ │ └── EnvironmentAwareMetricsBasePathSpec.groovy │ │ ├── tracing │ │ └── TracingPropertiesEnablerSpec.groovy │ │ └── web │ │ ├── correlationid │ │ ├── CorrelationIdAspectSpec.groovy │ │ ├── CorrelationIdAsyncSpec.groovy │ │ └── CorrelationIdFilterSpec.groovy │ │ ├── exception │ │ ├── CustomControllerAdvice.groovy │ │ ├── CustomControllerAdviceMvcSpec.groovy │ │ ├── ExceptionHandlingMvcSpec.groovy │ │ └── TestController.groovy │ │ ├── logging │ │ ├── FeignCallObfuscatingLoggerSpec.groovy │ │ ├── RequestDataProviderTest.groovy │ │ ├── RequestLoggingClientInterceptorSpec.groovy │ │ ├── RequestLoggingControllerFilterSpec.groovy │ │ ├── obfuscation │ │ │ ├── JsonPayloadObfuscatorSpec.groovy │ │ │ └── XmlPayloadObfuscatorSpec.groovy │ │ └── wrapper │ │ │ ├── DelegatingServletInputStreamSpec.groovy │ │ │ ├── DelegatingServletOutputStreamSpec.groovy │ │ │ ├── HttpServletRequestLoggingWrapperSpec.groovy │ │ │ └── HttpServletResponseLoggingWrapperSpec.groovy │ │ ├── resttemplate │ │ ├── RegexMatchingPathElidingURIMetricNamerSpec.groovy │ │ ├── RestOperationsMetricsAspectIntegrationSpec.groovy │ │ ├── custom │ │ │ ├── HttpStatusVerifierSpec.groovy │ │ │ ├── InputStreamPrinterSpec.groovy │ │ │ ├── ResponseRethrowingErrorHandlerSpec.groovy │ │ │ └── RestTemplateSpec.groovy │ │ └── fluent │ │ │ ├── ComponentWithTwoRestOperationsImplementations.groovy │ │ │ ├── FakeTrace.groovy │ │ │ ├── HTTPAuthorizationUtilsSpec.groovy │ │ │ ├── ServiceRestClientCustomizationByNameSpec.groovy │ │ │ ├── ServiceRestClientCustomizationSpec.groovy │ │ │ ├── ServiceRestClientIntegrationSpec.groovy │ │ │ ├── ServiceRestClientSpec.groovy │ │ │ ├── ServiceRestClientWebIntegrationSpec.groovy │ │ │ ├── TestRestTemplate.groovy │ │ │ ├── TwoRestOperationsImplementationsSpec.groovy │ │ │ ├── UrlUtilsSpec.groovy │ │ │ ├── common │ │ │ ├── CommonHttpMethodBuilderSpec.groovy │ │ │ ├── HttpMethodSpec.groovy │ │ │ ├── InvalidHttpMethodParametersSpec.groovy │ │ │ └── response │ │ │ │ ├── executor │ │ │ │ ├── HttpEntityUtilsSpec.groovy │ │ │ │ ├── RestExecutorSpec.groovy │ │ │ │ └── UrlParsingUtilsSpec.groovy │ │ │ │ └── receive │ │ │ │ └── PredefinedHttpHeadersSpec.groovy │ │ │ ├── delete │ │ │ └── DeleteHttpMethodBuilderSpec.groovy │ │ │ ├── get │ │ │ └── GetHttpMethodBuilderSpec.groovy │ │ │ ├── head │ │ │ └── HeadHttpMethodBuilderSpec.groovy │ │ │ ├── headers │ │ │ └── HeadersSettingSpec.groovy │ │ │ ├── options │ │ │ └── OptionsHttpMethodBuilderSpec.groovy │ │ │ ├── post │ │ │ └── PostHttpMethodBuilderSpec.groovy │ │ │ └── put │ │ │ └── PutHttpMethodBuilderSpec.groovy │ │ └── view │ │ ├── AcceptingUnquotedFieldsInJsonSpec.groovy │ │ ├── DisablingJsonGeneratorFeaturesSpec.groovy │ │ ├── DisablingJsonParserFeaturesSpec.groovy │ │ ├── EnablingJsonGeneratorFeaturesSpec.groovy │ │ ├── EnablingJsonParserFeaturesSpec.groovy │ │ ├── JacksonFeaturesTestConstants.groovy │ │ ├── JsonIgnoreUnknownPropertySpec.groovy │ │ ├── JsonJacksonFeaturesSpec.groovy │ │ ├── NoPrettyPrintingInProductionEnvironmentSpec.groovy │ │ ├── PrettyPrintingInDevelopmentEnvironmentSpec.groovy │ │ ├── SentJSONObjectsShouldBeCorrectlyDeserializedSpec.groovy │ │ └── TestController.groovy │ └── resources │ ├── application-aspect.properties │ ├── application-stub.properties │ ├── application-test.properties │ ├── graphitePublishingDisabled.properties │ ├── graphitePublishingEnabled.properties │ ├── graphiteWithDefaultProps.properties │ ├── logback-test.groovy │ ├── microservice.json │ ├── notPrettyPrinted.json │ ├── prettyPrinted.json │ └── requestLogging │ ├── message_req.json │ ├── message_req.xml │ ├── message_res.json │ └── message_res.xml ├── micro-infra-spring-boot-starter ├── build.gradle └── src │ └── main │ ├── java │ └── com.ofg.infrastructure.autoconfigure │ │ ├── MicroserviceAutoConfiguration.java │ │ ├── MicroserviceCircuitBreakingServletAutoConfiguration.java │ │ ├── MicroserviceDocumentationAutoConfiguration.java │ │ └── SpringCloudMicroSetup.java │ └── resources │ └── META-INF │ └── spring.factories ├── micro-infra-spring-config ├── README.md ├── build.gradle └── src │ ├── main │ ├── groovy │ │ └── com │ │ │ └── ofg │ │ │ └── infrastructure │ │ │ └── property │ │ │ └── LogbackConfiguration.groovy │ ├── java │ │ └── com │ │ │ └── ofg │ │ │ └── infrastructure │ │ │ └── property │ │ │ ├── AppCoordinates.java │ │ │ ├── ConfigLocations.java │ │ │ ├── EnableExternalProperties.java │ │ │ ├── ExternalPropertiesConfiguration.java │ │ │ ├── FileSystemLocator.java │ │ │ ├── FileSystemPoller.java │ │ │ ├── PollerConfiguration.java │ │ │ ├── PropertiesFolderFinder.java │ │ │ ├── PropertyUtils.java │ │ │ ├── SystemPropertiesOverridingPropertySourceLocator.java │ │ │ └── decrypt │ │ │ └── JceUnlimitedStrengthUtil.java │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ └── ruby │ │ └── aes.rb │ └── test │ ├── groovy │ └── com │ │ └── ofg │ │ └── infrastructure │ │ ├── property │ │ ├── AbstractIntegrationSpec.groovy │ │ ├── AppCoordinatesSpec.groovy │ │ ├── BootstrapPropertySourceOverrideSpec.groovy │ │ ├── ConfigLocationsSpec.groovy │ │ ├── FileSystemPollerSpec.groovy │ │ ├── LoadingFromFileSystemSpec.groovy │ │ ├── LoadingFromInvalidFileSpec.groovy │ │ ├── LogbackConfigurationSpec.groovy │ │ ├── PropertiesFolderFinderSpec.groovy │ │ └── decrypt │ │ │ ├── BrokenJceInstallationWarningSpec.groovy │ │ │ ├── DecryptingPropertyExtendedSpec.groovy │ │ │ ├── DecryptingPropertySpec.groovy │ │ │ ├── DecryptingPropertyTestApp.groovy │ │ │ ├── EncryptorTestUtil.groovy │ │ │ └── LoadingEncryptedFromFileSystemSpec.groovy │ │ └── spock │ │ ├── ClassLevelRestoreSystemProperties.java │ │ └── ClassLevelRestoreSystemPropertiesExtension.java │ └── resources │ ├── bootstrap-enc.yaml │ ├── bootstrap-invalid.yaml │ ├── bootstrap-ok.yaml │ ├── decryptingPropertyTest.properties │ ├── logback-test.groovy │ ├── microservice-enc.json │ ├── microservice-invalid.json │ ├── microservice.json │ ├── test-config-dir │ ├── common │ │ ├── com │ │ │ └── ofg │ │ │ │ ├── micro-app.properties │ │ │ │ ├── micro-app.yaml │ │ │ │ └── pl │ │ │ │ ├── micro-app-pl.properties │ │ │ │ └── micro-app-pl.yaml │ │ ├── global.properties │ │ └── global.yaml │ └── prod │ │ ├── com │ │ └── ofg │ │ │ ├── micro-app-enc.properties │ │ │ ├── micro-app-enc.yaml │ │ │ ├── micro-app.properties │ │ │ ├── micro-app.yaml │ │ │ └── pl │ │ │ ├── micro-app-pl.properties │ │ │ └── micro-app-pl.yaml │ │ └── io │ │ └── invalid-app.yaml │ ├── testConfigurationWithConfigurationProperties.properties │ └── testConfigurationWithPropertySource.properties ├── micro-infra-spring-swagger ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── ofg │ │ └── infrastructure │ │ └── web │ │ └── swagger │ │ └── SwaggerConfiguration.java │ └── resources │ └── .gitkeep ├── micro-infra-spring-test └── build.gradle ├── micro-infra-spring ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── ofg │ └── infrastructure │ └── config │ └── EnableMicroserviceDocumentation.java ├── settings.gradle └── stub-runner ├── stub-runner-spring ├── README.md ├── build.gradle └── src │ ├── main │ └── groovy │ │ └── com │ │ └── ofg │ │ └── stub │ │ ├── config │ │ ├── ServiceDiscoveryTestingServerConfiguration.groovy │ │ └── StubRunnerConfiguration.groovy │ │ └── util │ │ ├── CollaboratorsFromZookeeper.groovy │ │ └── PortResolver.java │ └── test │ └── groovy │ └── com │ └── ofg │ └── stub │ └── util │ ├── CollaboratorsFromZookeeperSpec.groovy │ └── PortResolverSpec.groovy └── stub-runner ├── README.md ├── build.gradle ├── repository ├── mappings │ ├── com │ │ └── ofg │ │ │ ├── another │ │ │ └── mapping.json │ │ │ ├── foo │ │ │ └── bar │ │ │ │ └── foobar.json │ │ │ └── ping │ │ │ └── ping.json │ └── pl │ │ └── com │ │ └── ofg │ │ └── foo │ │ └── bar │ │ └── pl_foobar.json └── projects │ ├── fooBar.json │ └── healthCheck.json └── src ├── main ├── groovy │ └── com │ │ └── ofg │ │ └── stub │ │ ├── AetherStubDownloader.groovy │ │ ├── Arguments.groovy │ │ ├── BatchStubRunner.groovy │ │ ├── BatchStubRunnerFactory.groovy │ │ ├── Collaborators.groovy │ │ ├── CollaboratorsPathResolver.groovy │ │ ├── DescriptorToCollaborators.groovy │ │ ├── StubDownloader.groovy │ │ ├── StubRunner.groovy │ │ ├── StubRunnerExecutor.groovy │ │ ├── StubRunnerFactory.groovy │ │ ├── StubRunnerMain.groovy │ │ ├── StubRunnerOptions.groovy │ │ ├── StubRunning.groovy │ │ ├── UnknownDependencyException.groovy │ │ ├── mapping │ │ ├── DescriptorRepository.groovy │ │ ├── InvalidRepositoryLayout.groovy │ │ ├── MappingDescriptor.groovy │ │ ├── NoContextProvidedException.groovy │ │ ├── ProjectMetadata.groovy │ │ ├── ProjectMetadataRepository.groovy │ │ └── StubRepository.groovy │ │ ├── registry │ │ └── StubRegistry.groovy │ │ ├── server │ │ ├── AvailablePortScanner.groovy │ │ ├── StubServer.groovy │ │ └── ZookeeperServer.groovy │ │ └── util │ │ └── ZipCategory.groovy └── resources │ └── microInfraGrapeConfig.xml └── test ├── groovy └── com │ └── ofg │ └── stub │ ├── BatchStubRunnerSpec.groovy │ ├── ProjectMetadataResolverSpec.groovy │ ├── StubRunnerExecutorSpec.groovy │ ├── StubRunnerFactorySpec.groovy │ ├── StubRunnerSpec.groovy │ ├── mapping │ ├── DescriptorRepositorySpec.groovy │ ├── MappingDescriptorSpec.groovy │ ├── ProjectMetadataRepositorySpec.groovy │ ├── ProjectMetadataSpec.groovy │ └── StubRepositorySpec.groovy │ ├── registry │ └── StubRegistrySpec.groovy │ ├── server │ ├── AvailablePortScannerSpec.groovy │ └── StubServerSpec.groovy │ └── util │ └── ZipCategorySpec.groovy └── resources ├── anotherRepository ├── mappings │ └── com │ │ └── ofg │ │ ├── bar │ │ └── bar.json │ │ └── foo │ │ ├── bar │ │ └── foobar.json │ │ └── foo.json └── projects │ ├── brokers │ ├── brokers.json │ └── nested │ │ └── anotherDescriptor.json │ └── descriptor.json ├── deepenMappingsRepository └── deeper │ └── located │ └── mappings │ ├── com │ └── ofg │ │ ├── bye │ │ ├── admin │ │ │ └── admin.json │ │ └── bye.json │ │ └── ping │ │ └── ping.json │ └── pl │ └── com │ └── ofg │ └── bye │ ├── pl_bye.json │ └── pl_overridden_bye.json ├── file.zip ├── microservice_example.json └── repository └── mappings ├── com └── ofg │ ├── bye │ ├── admin │ │ └── admin.json │ └── bye.json │ ├── hello │ ├── README.md │ ├── admin │ │ └── admin.json │ └── hello.json │ └── ping │ └── ping.json ├── lv └── com │ └── ofg │ └── bye │ └── lv_bye.json └── pl └── com └── ofg └── bye ├── pl_bye.json └── pl_overridden_bye.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | build/ 4 | /bin 5 | .gradle 6 | .poject 7 | .settings 8 | .classpath 9 | logs 10 | .log 11 | .zip 12 | out/ 13 | atlassian-ide-plugin.xml 14 | *~ 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # See: [Releases](https://github.com/4finance/micro-infra-spring/releases) 2 | -------------------------------------------------------------------------------- /activity-tracker-root/activity-tracker-boot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | io.fourfinance.activity_tracker.autoconfigure.ActivityTrackerAutoConfiguration -------------------------------------------------------------------------------- /activity-tracker-root/activity-tracker-boot-starter/src/test/java/io/fourfinance/activity_tracker/autoconfigure/ActivityTrackerAutoConfigurationDisabledTest.java: -------------------------------------------------------------------------------- 1 | package io.fourfinance.activity_tracker.autoconfigure; 2 | 3 | import io.fourfinance.activity_tracker.testapp.TestApplication; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.context.ApplicationContext; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import static org.assertj.core.api.BDDAssertions.then; 12 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; 13 | 14 | @RunWith(SpringRunner.class) 15 | @SpringBootTest(properties = "com.ofg.infra.microservice.track-activity.enabled = false", webEnvironment = NONE, classes = TestApplication.class) 16 | public class ActivityTrackerAutoConfigurationDisabledTest { 17 | 18 | @Autowired 19 | ApplicationContext context; 20 | 21 | @Test 22 | public void shouldNotLoadUserActivityTrackingBeans() throws Exception { 23 | //when 24 | boolean trackUserActivityAspectPresent = context.containsBean("trackUserActivityAspect"); 25 | 26 | //then 27 | then(trackUserActivityAspectPresent).isFalse(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /activity-tracker-root/activity-tracker-boot-starter/src/test/java/io/fourfinance/activity_tracker/autoconfigure/ActivityTrackerAutoConfigurationEnabledTest.java: -------------------------------------------------------------------------------- 1 | package io.fourfinance.activity_tracker.autoconfigure; 2 | 3 | import io.fourfinance.activity_tracker.testapp.TestApplication; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.context.ApplicationContext; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import static org.assertj.core.api.BDDAssertions.then; 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest(classes = TestApplication.class) 15 | public class ActivityTrackerAutoConfigurationEnabledTest { 16 | 17 | @Autowired 18 | ApplicationContext context; 19 | 20 | @Test 21 | public void shouldLoadUserActivityTrackingBeans() throws Exception { 22 | //when 23 | boolean trackUserActivityAspectPresent = context.containsBean("trackUserActivityAspect"); 24 | 25 | //then 26 | then(trackUserActivityAspectPresent).isTrue(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /activity-tracker-root/activity-tracker-boot-starter/src/test/java/io/fourfinance/activity_tracker/testapp/TestApplication.java: -------------------------------------------------------------------------------- 1 | package io.fourfinance.activity_tracker.testapp; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TestApplication { 8 | public static void main(String[] args) { 9 | SpringApplication application = new SpringApplication(TestApplication.class); 10 | application.run(args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /activity-tracker-root/activity-tracker/src/main/java/io/fourfinance/activity_tracker/activity/ActivityParameters.java: -------------------------------------------------------------------------------- 1 | package io.fourfinance.activity_tracker.activity; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public class ActivityParameters { 7 | 8 | private final List parameters; 9 | 10 | public ActivityParameters(String... parameters) { 11 | this.parameters = Arrays.asList(parameters); 12 | } 13 | 14 | public static ActivityParameters emptyActivityParameters(){ 15 | return new ActivityParameters(); 16 | } 17 | 18 | public List getParameters() { 19 | return parameters; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /activity-tracker-root/activity-tracker/src/main/java/io/fourfinance/activity_tracker/activity/TrackUserActivity.java: -------------------------------------------------------------------------------- 1 | package io.fourfinance.activity_tracker.activity; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.METHOD) 10 | public @interface TrackUserActivity { 11 | 12 | String value() default "empty"; 13 | } 14 | -------------------------------------------------------------------------------- /activity-tracker-root/activity-tracker/src/main/java/io/fourfinance/activity_tracker/activity/TrackUserActivityMetrics.java: -------------------------------------------------------------------------------- 1 | package io.fourfinance.activity_tracker.activity; 2 | 3 | public interface TrackUserActivityMetrics { 4 | 5 | void process(String activityName); 6 | } 7 | -------------------------------------------------------------------------------- /activity-tracker-root/activity-tracker/src/main/java/io/fourfinance/activity_tracker/audit/DefaultTrackUserActivityAudits.java: -------------------------------------------------------------------------------- 1 | package io.fourfinance.activity_tracker.audit; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | import java.util.Map; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import io.fourfinance.activity_tracker.activity.TrackUserActivityAspect; 10 | 11 | public class DefaultTrackUserActivityAudits implements TrackUserActivityAudits { 12 | 13 | private final static Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); 14 | 15 | @Override 16 | public void audit(Map parameters) { 17 | LOG.info("Activity {}", parameters.get(TrackUserActivityAspect.ACTIVITY_NAME)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /activity-tracker-root/activity-tracker/src/main/java/io/fourfinance/activity_tracker/audit/TrackUserActivityAudits.java: -------------------------------------------------------------------------------- 1 | package io.fourfinance.activity_tracker.audit; 2 | 3 | import java.util.Map; 4 | 5 | public interface TrackUserActivityAudits { 6 | 7 | void audit(Map parameters); 8 | } 9 | -------------------------------------------------------------------------------- /activity-tracker-root/build.gradle: -------------------------------------------------------------------------------- 1 | subprojects { 2 | apply plugin: 'java' 3 | apply plugin: 'groovy' 4 | 5 | sourceCompatibility = 1.8 6 | targetCompatibility = 1.8 7 | 8 | dependencies { 9 | compile 'org.aspectj:aspectjrt' 10 | testCompile 'junit:junit:4.12' 11 | testCompile 'org.codehaus.groovy:groovy-all' 12 | testCompile 'org.spockframework:spock-core' 13 | } 14 | } 15 | 16 | project(':activity-tracker-root:activity-tracker') { 17 | dependencies { 18 | compile 'org.aspectj:aspectjweaver' 19 | compile 'io.dropwizard.metrics:metrics-core' 20 | compile 'commons-beanutils:commons-beanutils:1.9.3' 21 | compile 'com.google.guava:guava' 22 | } 23 | } 24 | 25 | project(':activity-tracker-root:activity-tracker-boot-starter') { 26 | dependencies { 27 | compile project(':activity-tracker-root:activity-tracker') 28 | compile 'org.springframework.boot:spring-boot-starter' 29 | testCompile 'org.springframework.boot:spring-boot-starter-test' 30 | testCompile 'org.assertj:assertj-core' 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | #org.gradle.daemon=true 2 | #org.gradle.parallel=true 3 | 4 | mavenUser= 5 | mavenPassword= 6 | mavenRepoUrl=http://fat-jars-change-it/ 7 | aetherVersion=1.1.0 -------------------------------------------------------------------------------- /gradle/runBootMicroserviceAcceptanceTests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | function dumpCurrentMicroInfraSpringVersionToFile { 4 | 5 | ./gradlew -q currentVersion | grep "Project version" | sed s/Project\ version\:\ //g > ~/.microInfraSpringCurrentVersion.txt 6 | cat ~/.microInfraSpringCurrentVersion.txt 7 | } 8 | 9 | function updateMicroInfraSpringVersionInConfigurationFile { 10 | echo -e "\nmicroInfraSpringVersion="`cat ~/.microInfraSpringCurrentVersion.txt` >> gradle.properties 11 | cat gradle.properties 12 | } 13 | 14 | set -e 15 | dumpCurrentMicroInfraSpringVersionToFile 16 | 17 | git clone https://github.com/4finance/boot-microservice.git 18 | cd boot-microservice 19 | updateMicroInfraSpringVersionInConfigurationFile 20 | ./gradlew clean check guiTest uptodate --stacktrace --continue --no-daemon --info -Dwebdriver=chrome 21 | -------------------------------------------------------------------------------- /gradle/setGitVariables.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo Configuring Git for pushing to GH... 4 | 5 | git config user.email "4financebot@gmail.com" 6 | git config user.name "4Finance Bot" 7 | git config push.default simple 8 | git remote set-url origin "https://github.com/${TRAVIS_REPO_SLUG}.git" 9 | 10 | echo Git configured 11 | -------------------------------------------------------------------------------- /gradle/version.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'pl.allegro.tech.build.axion-release' 2 | 3 | scmVersion { 4 | createReleaseCommit = true 5 | releaseCommitMessage { version, position -> "release version: ${version}\n\n[ci skip]" } 6 | dryRun = project.hasProperty("dryRun") 7 | } 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/4finance/micro-infra-spring/2479deec28bad8c9b05cbae92219041c34a39261/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-jax-rs-jersey/src/test/java/com/ofg/infrastructure/jaxrs/JaxRsApi.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.jaxrs; 2 | 3 | import javax.ws.rs.GET; 4 | import javax.ws.rs.Path; 5 | 6 | @Path("hello") 7 | public interface JaxRsApi { 8 | String HELLO = "Hello JAX-RS"; 9 | 10 | @GET 11 | @Path("get") 12 | String getHello(); 13 | } 14 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-jax-rs-jersey/src/test/java/com/ofg/infrastructure/jerseys/JerseyApplication.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.jerseys; 2 | 3 | import org.slf4j.bridge.SLF4JBridgeHandler; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | import org.springframework.boot.web.support.SpringBootServletInitializer; 7 | 8 | @SpringBootApplication 9 | public class JerseyApplication extends SpringBootServletInitializer { 10 | 11 | @Override 12 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 13 | return application.sources(JerseyApplication.class); 14 | } 15 | 16 | public static void main(String[] args) { 17 | SLF4JBridgeHandler.removeHandlersForRootLogger(); 18 | SLF4JBridgeHandler.install(); 19 | new JerseyApplication().configure( 20 | new SpringApplicationBuilder(JerseyApplication.class) 21 | ).run(args); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-jax-rs-jersey/src/test/java/com/ofg/infrastructure/jerseys/JerseyConfig.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.jerseys; 2 | 3 | import org.glassfish.jersey.server.ResourceConfig; 4 | import org.springframework.stereotype.Component; 5 | 6 | import javax.ws.rs.ApplicationPath; 7 | 8 | @Component 9 | @ApplicationPath("ctx") 10 | public class JerseyConfig extends ResourceConfig { 11 | public JerseyConfig() { 12 | register(JerseyResource.class); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-jax-rs-jersey/src/test/java/com/ofg/infrastructure/jerseys/JerseyResource.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.jerseys; 2 | 3 | import com.ofg.infrastructure.jaxrs.JaxRsApi; 4 | import org.springframework.stereotype.Controller; 5 | 6 | @Controller 7 | public class JerseyResource implements JaxRsApi { 8 | 9 | @Override 10 | public String getHello() { 11 | return JaxRsApi.HELLO; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/main/java/com/ofg/config/BasicProfiles.java: -------------------------------------------------------------------------------- 1 | package com.ofg.config; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | /** 7 | * 4finance default Spring profiles 8 | */ 9 | public class BasicProfiles { 10 | 11 | /** 12 | * Profile used for development. Starts Zookeeper and stubs. 13 | */ 14 | public static final String DEVELOPMENT = "dev"; 15 | /** 16 | * Profile used for any environment to run microservice in production mode. 17 | */ 18 | public static final String PRODUCTION = "prod"; 19 | /** 20 | * Profile used for integration and unit tests 21 | */ 22 | public static final String TEST = "test"; 23 | /** 24 | * Third party services should be mocked in smokeTests profile to guarantee pipeline stability 25 | */ 26 | public static final String SMOKE_TESTS = "smokeTests"; 27 | 28 | public static final String SPRING_CLOUD = "springCloud"; 29 | 30 | public static List all() { 31 | return Arrays.asList(DEVELOPMENT, PRODUCTION, TEST, SMOKE_TESTS, SPRING_CLOUD); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/main/java/com/ofg/config/NotSpringCloudProfile.java: -------------------------------------------------------------------------------- 1 | package com.ofg.config; 2 | 3 | import org.springframework.context.annotation.Profile; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target({ElementType.TYPE, ElementType.METHOD}) 12 | @Profile("!"+BasicProfiles.SPRING_CLOUD) 13 | public @interface NotSpringCloudProfile { 14 | } 15 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/main/java/com/ofg/infrastructure/discovery/ConsumerDrivenContractConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | import com.ofg.config.BasicProfiles; 4 | import com.ofg.infrastructure.discovery.ZookeeperConnectorConditions.InMemoryZookeeperCondition; 5 | import com.ofg.stub.config.StubRunnerConfiguration; 6 | import org.springframework.context.annotation.Conditional; 7 | import org.springframework.context.annotation.Import; 8 | 9 | /** 10 | * Configuration that under {@link BasicProfiles#TEST} and {@link BasicProfiles#DEVELOPMENT} 11 | * registers the {@link StubRunnerConfiguration} 12 | * 13 | * @see ZookeeperConnectorConditions 14 | */ 15 | @Conditional(InMemoryZookeeperCondition.class) 16 | @Import(StubRunnerConfiguration.class) 17 | public class ConsumerDrivenContractConfiguration { 18 | } 19 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/main/java/com/ofg/infrastructure/discovery/MicroserviceAddressProvider.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | /** 4 | * Holder for microservice's host and port 5 | */ 6 | @Deprecated 7 | public class MicroserviceAddressProvider { 8 | private final String host; 9 | private final int port; 10 | 11 | public MicroserviceAddressProvider(String microserviceHost, int microservicePort) { 12 | this.host = microserviceHost; 13 | this.port = microservicePort; 14 | } 15 | 16 | public String getHost() { 17 | return host; 18 | } 19 | 20 | public int getPort() { 21 | return port; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/main/java/com/ofg/infrastructure/discovery/MicroserviceJsonConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | import com.ofg.config.NotSpringCloudProfile; 4 | import org.springframework.boot.autoconfigure.AutoConfigureBefore; 5 | import org.springframework.cloud.zookeeper.ZookeeperAutoConfiguration; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.context.annotation.Import; 8 | 9 | @Configuration 10 | @Deprecated 11 | @NotSpringCloudProfile 12 | @Import({AddressProviderConfiguration.class, ServiceDiscoveryInfrastructureConfiguration.class, DependencyResolutionConfiguration.class}) 13 | @AutoConfigureBefore(ZookeeperAutoConfiguration.class) 14 | public class MicroserviceJsonConfiguration { 15 | } 16 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/main/java/com/ofg/infrastructure/discovery/ServiceResolverConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | import org.springframework.boot.autoconfigure.ImportAutoConfiguration; 4 | import org.springframework.cloud.commons.util.UtilAutoConfiguration; 5 | import org.springframework.cloud.sleuth.log.SleuthLogAutoConfiguration; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.context.annotation.Import; 8 | 9 | /** 10 | * Configuration that binds together whole service discovery 11 | */ 12 | @Import({MicroserviceJsonConfiguration.class, SpringCloudZookeeperConfiguration.class }) 13 | @ImportAutoConfiguration({ UtilAutoConfiguration.class, SleuthLogAutoConfiguration.class }) 14 | @Configuration 15 | public class ServiceResolverConfiguration { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/main/java/com/ofg/infrastructure/discovery/ZookeeperConnector.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | public interface ZookeeperConnector { 4 | String getServiceResolverUrl(); 5 | } 6 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/main/resources/application-test.yaml: -------------------------------------------------------------------------------- 1 | spring.jmx.enabled: false -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/test/groovy/com/ofg/infrastructure/discovery/config/ConfigWithEnvironment.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.config 2 | 3 | import groovy.transform.CompileStatic 4 | import org.springframework.context.annotation.Configuration 5 | import org.springframework.context.annotation.PropertySource 6 | 7 | @Configuration 8 | @PropertySource('classpath:microservice.properties') 9 | @CompileStatic 10 | class ConfigWithEnvironment { 11 | } 12 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/test/groovy/com/ofg/infrastructure/discovery/config/PropertySourceConfiguration.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.config 2 | 3 | import groovy.transform.CompileStatic 4 | import org.springframework.context.annotation.Bean 5 | import org.springframework.context.annotation.Configuration 6 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer 7 | 8 | @Configuration 9 | @CompileStatic 10 | class PropertySourceConfiguration { 11 | 12 | @Bean static PropertySourcesPlaceholderConfigurer propertiesConfigurer() { 13 | Properties properties = new Properties() 14 | properties.setProperty('stubrunner.stubs.repository.root', 'http://dl.bintray.com/4finance/micro') 15 | properties.setProperty('stubrunner.stubs.group', 'com.ofg') 16 | properties.setProperty('stubrunner.stubs.module', 'stub-runner-examples') 17 | properties.setProperty('microservice.config.file', 'classpath:stub-microservice.json') 18 | return new PropertySourcesPlaceholderConfigurer(properties: properties) 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/test/resources/logback-test.groovy: -------------------------------------------------------------------------------- 1 | import ch.qos.logback.classic.encoder.PatternLayoutEncoder 2 | import ch.qos.logback.core.ConsoleAppender 3 | import org.springframework.cloud.sleuth.Span 4 | 5 | import static ch.qos.logback.classic.Level.DEBUG 6 | import static ch.qos.logback.classic.Level.INFO 7 | 8 | appender("CONSOLE", ConsoleAppender) { 9 | encoder(PatternLayoutEncoder) { 10 | pattern = "%d{HH:mm:ss.SSSZ} | %-5level | %X{${Span.TRACE_ID_NAME}} | %thread | %logger{1} | %m%n" 11 | } 12 | } 13 | 14 | root(INFO, ["CONSOLE"]) 15 | 16 | logger("com.ofg", DEBUG) 17 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/test/resources/microservice.properties: -------------------------------------------------------------------------------- 1 | server.port=1234567 2 | wiremock.port=8030 3 | microservice.config.file=classpath:test-microservice.json -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-config/src/test/resources/stub-microservice.json: -------------------------------------------------------------------------------- 1 | { 2 | "pl": { 3 | "this": "com/ofg/stub-runner/tester", 4 | "dependencies": { 5 | "foo-bar" : { 6 | "path": "com/ofg/foo/bar", 7 | "required": true 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-test-config/src/main/groovy/com/ofg/infrastructure/base/IntegrationSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.base 2 | 3 | import groovy.transform.CompileStatic 4 | import org.springframework.context.annotation.EnableAspectJAutoProxy 5 | import org.springframework.test.context.ActiveProfiles 6 | import org.springframework.test.context.web.WebAppConfiguration 7 | import spock.lang.Specification 8 | 9 | import static com.ofg.config.BasicProfiles.TEST 10 | 11 | /** 12 | * Base specification class for Spring's web application 13 | */ 14 | @CompileStatic 15 | @WebAppConfiguration 16 | @EnableAspectJAutoProxy(proxyTargetClass = true) 17 | @ActiveProfiles(TEST) 18 | abstract class IntegrationSpec extends Specification { 19 | } 20 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-test-config/src/main/groovy/com/ofg/infrastructure/base/IntegrationTest.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.base 2 | 3 | import groovy.transform.CompileStatic 4 | import org.junit.runner.RunWith 5 | import org.springframework.context.annotation.EnableAspectJAutoProxy 6 | import org.springframework.test.context.ActiveProfiles 7 | import org.springframework.test.context.junit4.SpringRunner 8 | import org.springframework.test.context.web.WebAppConfiguration 9 | 10 | import static com.ofg.config.BasicProfiles.TEST 11 | 12 | /** 13 | * Base JUnit test class for Spring's web application 14 | */ 15 | @CompileStatic 16 | @RunWith(SpringRunner) 17 | @EnableAspectJAutoProxy(proxyTargetClass = true) 18 | @WebAppConfiguration 19 | @ActiveProfiles(TEST) 20 | abstract class IntegrationTest { 21 | } 22 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-test-config/src/main/groovy/com/ofg/infrastructure/base/dsl/WireMockHttpRequestMapper.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.base.dsl 2 | 3 | import com.github.tomakehurst.wiremock.client.MappingBuilder 4 | import com.github.tomakehurst.wiremock.client.WireMock 5 | import groovy.transform.CompileStatic 6 | 7 | /** 8 | * A class that contains static helper methods that map HTTP methods with given path 9 | */ 10 | @CompileStatic 11 | class WireMockHttpRequestMapper { 12 | 13 | static MappingBuilder wireMockGet(String path) { 14 | return WireMock.get(WireMock.urlEqualTo(path)) 15 | } 16 | 17 | static MappingBuilder wireMockPut(String path) { 18 | return WireMock.put(WireMock.urlEqualTo(path)) 19 | } 20 | 21 | static MappingBuilder wireMockPost(String path) { 22 | return WireMock.post(WireMock.urlEqualTo(path)) 23 | } 24 | 25 | static MappingBuilder wireMockDelete(String path) { 26 | return WireMock.delete(WireMock.urlEqualTo(path)) 27 | } 28 | 29 | static MappingBuilder wireMockOptions(String path) { 30 | return WireMock.options(WireMock.urlEqualTo(path)) 31 | } 32 | 33 | static MappingBuilder wireMockHead(String path) { 34 | return WireMock.head(WireMock.urlEqualTo(path)) 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-test-config/src/main/groovy/com/ofg/infrastructure/discovery/web/HttpMockServer.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.web 2 | 3 | import com.github.tomakehurst.wiremock.WireMockServer 4 | import com.github.tomakehurst.wiremock.core.Options 5 | import groovy.transform.CompileStatic 6 | 7 | /** 8 | * Custom implementation of {@link WireMockServer} that by default registers itself at port 9 | * {@link HttpMockServer#DEFAULT_PORT}. 10 | * 11 | * @see WireMockServer 12 | */ 13 | @CompileStatic 14 | class HttpMockServer extends WireMockServer { 15 | 16 | public static final int DEFAULT_PORT = 8030 17 | 18 | HttpMockServer(int port) { 19 | super(port) 20 | } 21 | 22 | HttpMockServer() { 23 | super(DEFAULT_PORT) 24 | } 25 | 26 | HttpMockServer(Options options) { 27 | super(options) 28 | } 29 | 30 | void shutdownServer() { 31 | if (isRunning()) { 32 | stop() 33 | } 34 | shutdown() 35 | } 36 | } -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-test-config/src/test/groovy/com/ofg/infrastructure/BaseConfiguration.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure 2 | 3 | import groovy.transform.TypeChecked 4 | import org.springframework.context.annotation.Bean 5 | import org.springframework.context.annotation.Configuration 6 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer 7 | import org.springframework.core.io.ClassPathResource 8 | 9 | @TypeChecked 10 | @Configuration 11 | class BaseConfiguration { 12 | 13 | @Bean 14 | static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 15 | PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer() 16 | propertySourcesPlaceholderConfigurer.location = new ClassPathResource('application-test.properties') 17 | return propertySourcesPlaceholderConfigurer 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-test-config/src/test/resources/application-test.properties: -------------------------------------------------------------------------------- 1 | wiremock.port=8030 2 | microservice.config.file=classpath:test-microservice.json 3 | stubrunner.stubs.group=com.ofg 4 | stubrunner.stubs.module=stub-runner-examples 5 | stubrunner.stubs.repository.root=http://dl.bintray.com/4finance/micro -------------------------------------------------------------------------------- /micro-deps/micro-deps-spring-test-config/src/test/resources/test-microservice.json: -------------------------------------------------------------------------------- 1 | { 2 | "pl": { 3 | "this": "test-twitter-places-analyzer", 4 | "dependencies": { 5 | "correlator" : { 6 | "path": "com/ofg/correlator" 7 | } 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/InvalidMicroserviceConfigurationException.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | public class InvalidMicroserviceConfigurationException extends RuntimeException { 4 | public InvalidMicroserviceConfigurationException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/MicroserviceConfigurationNotPresentException.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | public class MicroserviceConfigurationNotPresentException extends RuntimeException { 4 | } 5 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/ServiceAlias.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | import org.apache.commons.lang.builder.EqualsBuilder; 4 | import org.apache.commons.lang.builder.HashCodeBuilder; 5 | import org.apache.commons.lang.builder.ReflectionToStringBuilder; 6 | 7 | /** 8 | * Alias to service as used e.g. in {@code ServiceRestClient} 9 | * You can translate from alias to path using {@link ServiceResolver#resolveAlias(ServiceAlias)}. 10 | */ 11 | public class ServiceAlias { 12 | private final String name; 13 | 14 | public ServiceAlias(String name) { 15 | this.name = name; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return name; 25 | } 26 | 27 | @Override 28 | public int hashCode() { 29 | return HashCodeBuilder.reflectionHashCode(this); 30 | } 31 | 32 | @Override 33 | public boolean equals(Object o) { 34 | return EqualsBuilder.reflectionEquals(this, o); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/ServiceConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | public class ServiceConfigurationProperties { 4 | public static final String PATH = "path"; 5 | public static final String REQUIRED = "required"; 6 | public static final String VERSION = "version"; 7 | public static final String CONTENT_TYPE_TEMPLATE = "contentTypeTemplate"; 8 | public static final String HEADERS = "headers"; 9 | public static final String LOAD_BALANCER = "load-balancer"; 10 | public static final String DEPENDENCIES = "dependencies"; 11 | public static final String THIS = "this"; 12 | public static final String STUBS = "stubs"; 13 | } 14 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/ServiceUnavailableException.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | public class ServiceUnavailableException extends RuntimeException { 4 | public ServiceUnavailableException(ServicePath path) { 5 | super("No services availabe under path [" + path + "]"); 6 | } 7 | 8 | /** 9 | * 10 | * @deprecated since 0.9.1, use {@link #ServiceUnavailableException(ServicePath path)} instead 11 | */ 12 | @Deprecated 13 | public ServiceUnavailableException(String path) { 14 | super("No services availabe under path [" + path + "]"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/util/LoadBalancerType.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.util; 2 | 3 | import com.google.common.base.Predicate; 4 | import org.apache.commons.lang.StringUtils; 5 | 6 | import java.util.Arrays; 7 | 8 | import static org.apache.commons.lang.StringUtils.EMPTY; 9 | import static org.apache.commons.lang.StringUtils.defaultIfEmpty; 10 | 11 | public enum LoadBalancerType { 12 | STICKY, RANDOM, ROUND_ROBIN; 13 | 14 | public static LoadBalancerType fromName(final String strategyName) { 15 | LoadBalancerType loadBalancerType = CollectionUtils.find(Arrays.asList(values()), new Predicate() { 16 | @Override 17 | public boolean apply(LoadBalancerType input) { 18 | return input.name().equals(defaultIfEmpty(strategyName, EMPTY).toUpperCase()); 19 | } 20 | 21 | }); 22 | if (loadBalancerType == null) { 23 | return ROUND_ROBIN; 24 | } 25 | return loadBalancerType; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/util/ProviderStrategyFactory.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.util; 2 | 3 | import org.apache.curator.x.discovery.ProviderStrategy; 4 | import org.apache.curator.x.discovery.strategies.RandomStrategy; 5 | import org.apache.curator.x.discovery.strategies.RoundRobinStrategy; 6 | import org.apache.curator.x.discovery.strategies.StickyStrategy; 7 | 8 | public class ProviderStrategyFactory { 9 | 10 | public ProviderStrategy createProviderStrategy(LoadBalancerType type) { 11 | switch (type) { 12 | case ROUND_ROBIN: 13 | return new RoundRobinStrategy<>(); 14 | case RANDOM: 15 | return new RandomStrategy<>(); 16 | case STICKY: 17 | return new StickyStrategy<>(new RoundRobinStrategy<>()); 18 | default: 19 | throw new IllegalArgumentException("Unknown load balancer type " + type); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/watcher/DependencyState.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.watcher; 2 | 3 | public enum DependencyState { 4 | CONNECTED, 5 | DISCONNECTED 6 | } 7 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/watcher/DependencyWatcherListener.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.watcher; 2 | 3 | /** 4 | * Performs logic upon change of state of a dependency {@see DependencyState} 5 | * in the service discovery system. 6 | */ 7 | public interface DependencyWatcherListener { 8 | 9 | /** 10 | * Method executed upon state change of a dependency 11 | * 12 | * @param dependencyName - alias from microservice configuration {@see ServiceConfigurationResolver} 13 | * @param newState 14 | */ 15 | void stateChanged(String dependencyName, DependencyState newState); 16 | } 17 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/watcher/presence/DefaultDependencyPresenceOnStartupVerifier.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.watcher.presence; 2 | 3 | import com.ofg.infrastructure.discovery.watcher.presence.checker.LogMissingDependencyChecker; 4 | 5 | public class DefaultDependencyPresenceOnStartupVerifier extends DependencyPresenceOnStartupVerifier { 6 | public DefaultDependencyPresenceOnStartupVerifier() { 7 | super(new LogMissingDependencyChecker()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/watcher/presence/DependencyPresenceOnStartupVerifier.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.watcher.presence; 2 | 3 | import com.ofg.infrastructure.discovery.watcher.presence.checker.FailOnMissingDependencyChecker; 4 | import com.ofg.infrastructure.discovery.watcher.presence.checker.PresenceChecker; 5 | import org.apache.curator.x.discovery.ServiceCache; 6 | 7 | @SuppressWarnings("unchecked") 8 | public abstract class DependencyPresenceOnStartupVerifier { 9 | private static final PresenceChecker MANDATORY_DEPENDENCY_CHECKER = new FailOnMissingDependencyChecker(); 10 | private final PresenceChecker optionalDependencyChecker; 11 | 12 | public DependencyPresenceOnStartupVerifier(PresenceChecker optionalDependencyChecker) { 13 | this.optionalDependencyChecker = optionalDependencyChecker; 14 | } 15 | 16 | public void verifyDependencyPresence(String dependencyName, ServiceCache serviceCache, boolean required) { 17 | if (required) { 18 | MANDATORY_DEPENDENCY_CHECKER.checkPresence(dependencyName, serviceCache.getInstances()); 19 | } else { 20 | optionalDependencyChecker.checkPresence(dependencyName, serviceCache.getInstances()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/watcher/presence/checker/FailOnMissingDependencyChecker.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.watcher.presence.checker; 2 | 3 | import org.apache.curator.x.discovery.ServiceInstance; 4 | 5 | import java.util.List; 6 | 7 | public class FailOnMissingDependencyChecker implements PresenceChecker { 8 | @Override 9 | public void checkPresence(String dependencyName, List serviceInstances) { 10 | if (serviceInstances.isEmpty()) { 11 | throw new NoInstancesRunningException(dependencyName); 12 | } 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/watcher/presence/checker/LogMissingDependencyChecker.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.watcher.presence.checker; 2 | 3 | import org.apache.curator.x.discovery.ServiceInstance; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.lang.invoke.MethodHandles; 8 | import java.util.List; 9 | 10 | public class LogMissingDependencyChecker implements PresenceChecker { 11 | 12 | private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); 13 | 14 | @Override 15 | public void checkPresence(String dependencyName, List serviceInstances) { 16 | if (serviceInstances.isEmpty()) { 17 | log.warn("Microservice dependency with name [" + dependencyName + "] is missing."); 18 | } 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/watcher/presence/checker/NoInstancesRunningException.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.watcher.presence.checker; 2 | 3 | public class NoInstancesRunningException extends RuntimeException { 4 | public NoInstancesRunningException(String dependencyName) { 5 | super("Required microservice dependency with name [" + dependencyName + "] is missing"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/main/java/com/ofg/infrastructure/discovery/watcher/presence/checker/PresenceChecker.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.watcher.presence.checker; 2 | 3 | import org.apache.curator.x.discovery.ServiceInstance; 4 | 5 | import java.util.List; 6 | 7 | public interface PresenceChecker { 8 | 9 | /** 10 | * Checks if a given dependency is present 11 | * 12 | * @param dependencyName 13 | * @param serviceInstances - instances to check the dependency for 14 | */ 15 | void checkPresence(String dependencyName, List serviceInstances); 16 | } 17 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/test/groovy/com/ofg/infrastructure/discovery/ServicePathSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery 2 | 3 | import spock.lang.Specification 4 | import spock.lang.Unroll 5 | 6 | class ServicePathSpec extends Specification { 7 | 8 | def "should retrieve last name [#expectedLastName] for path [#path]"() { 9 | expect: 10 | new ServicePath(path).lastName == expectedLastName 11 | where: 12 | path || expectedLastName 13 | '/io/fourfinanceit/somename' || 'somename' 14 | 'somename' || 'somename' 15 | null || '' 16 | } 17 | 18 | def "should retrieve path to last name [#expectedPathToLastName] for path [#path]"() { 19 | expect: 20 | new ServicePath(path).pathToLastName == expectedPathToLastName 21 | where: 22 | path || expectedPathToLastName 23 | '/io/fourfinanceit/somename' || '/io/fourfinanceit' 24 | 'somename' || 'somename' 25 | null || '' 26 | } 27 | 28 | def "should retrieve path with a starting slash"() { 29 | given: 30 | String path = 'io/fourfinanceit/somename' 31 | expect: 32 | new ServicePath(path).pathWithStartingSlash == "/$path" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/test/groovy/com/ofg/infrastructure/discovery/ServiceResolverSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery 2 | 3 | import com.ofg.infrastructure.base.SpecWithZookeper 4 | import com.ofg.infrastructure.discovery.watcher.DependencyWatcher 5 | import com.ofg.infrastructure.discovery.watcher.presence.DefaultDependencyPresenceOnStartupVerifier 6 | import com.ofg.infrastructure.discovery.watcher.presence.checker.NoInstancesRunningException 7 | 8 | import static org.codehaus.groovy.runtime.StackTraceUtils.extractRootCause 9 | import static MicroserviceConfigurationUtil.REQUIRED_DEPENDENCY 10 | 11 | class ServiceResolverSpec extends SpecWithZookeper { 12 | 13 | @Override 14 | String serviceConfig() { 15 | return REQUIRED_DEPENDENCY 16 | } 17 | 18 | def 'should throw exception if obligatory dependencies are missing'() { 19 | given: 20 | DependencyWatcher dependencyWatcher = new DependencyWatcher(serviceConfigurationResolver.dependencies, serviceDiscovery, 21 | new DefaultDependencyPresenceOnStartupVerifier() ) 22 | when: 23 | dependencyWatcher.registerDependencies() 24 | then: 25 | Throwable thrown = thrown(Throwable) 26 | extractRootCause(thrown).class == NoInstancesRunningException 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/test/groovy/com/ofg/infrastructure/discovery/StubsConfigurationSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery 2 | 3 | import spock.lang.Specification 4 | 5 | import static com.ofg.infrastructure.discovery.MicroserviceConfiguration.Dependency.StubsConfiguration 6 | 7 | class StubsConfigurationSpec extends Specification { 8 | 9 | def "should print stubs configuration in colon separated notation"() { 10 | expect: 11 | new StubsConfiguration('foo.bar', 'artifact', 'classifier').toColonSeparatedDependencyNotation() == 'foo.bar:artifact:classifier' 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/test/groovy/com/ofg/infrastructure/discovery/util/CollectionUtilsSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.util 2 | 3 | import com.google.common.base.Predicate 4 | import spock.lang.Specification 5 | 6 | class CollectionUtilsSpec extends Specification { 7 | 8 | def 'should return a value if exists in collection'() { 9 | given: 10 | List collection = [1, 2, 3] 11 | expect: 12 | 2 == CollectionUtils.find(collection, { Integer input -> return input == 2 } as Predicate) 13 | } 14 | 15 | def 'should return null if value does not exist in collection'() { 16 | given: 17 | List collection = [1, 2, 3] 18 | expect: 19 | !CollectionUtils.find(collection, { Integer input -> return input == 4 } as Predicate) 20 | } 21 | 22 | def 'should convert a collection to a set'() { 23 | given: 24 | List collection = [1, 2, 3, 3] 25 | expect: 26 | [1,2,3] as Set == CollectionUtils.toSet(collection) 27 | } 28 | 29 | def 'should flatten a collection'() { 30 | given: 31 | List collection = [1, [2], [[3, 3]]] 32 | expect: 33 | [1, 2, 3, 3] == CollectionUtils.flatten(collection, Integer) 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/test/groovy/com/ofg/infrastructure/discovery/util/LoadBalancerTypeSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.util 2 | 3 | import spock.lang.Specification 4 | import spock.lang.Unroll 5 | 6 | class LoadBalancerTypeSpec extends Specification { 7 | 8 | def 'should return ROUND_ROBIN if invalid value [#value] has been provided'() { 9 | expect: 10 | LoadBalancerType.ROUND_ROBIN == LoadBalancerType.fromName(value) 11 | where: 12 | value << [null, 'NON_EXISTING_VALUE'] 13 | } 14 | 15 | def 'should return proper enum if existing value of enum has been provided'() { 16 | expect: 17 | LoadBalancerType.STICKY == LoadBalancerType.fromName('sticky') 18 | } 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/test/groovy/com/ofg/infrastructure/discovery/util/ProviderStrategyFactorySpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.util 2 | 3 | import org.apache.curator.x.discovery.strategies.RandomStrategy 4 | import org.apache.curator.x.discovery.strategies.RoundRobinStrategy 5 | import org.apache.curator.x.discovery.strategies.StickyStrategy 6 | import spock.lang.Specification 7 | import spock.lang.Unroll 8 | 9 | import static com.ofg.infrastructure.discovery.util.LoadBalancerType.* 10 | 11 | class ProviderStrategyFactorySpec extends Specification { 12 | 13 | def 'should create #strategyProviderName provider for #strategyName'() { 14 | given: 15 | ProviderStrategyFactory factory = new ProviderStrategyFactory() 16 | when: 17 | def strategyProvider = factory.createProviderStrategy(strategyName) 18 | then: 19 | strategyProvider.class == strategyProviderName 20 | where: 21 | strategyName | strategyProviderName 22 | STICKY | StickyStrategy 23 | RANDOM | RandomStrategy 24 | ROUND_ROBIN | RoundRobinStrategy 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/test/groovy/com/ofg/infrastructure/discovery/watcher/presence/DefaultDependencyPresenceOnStartupVerifierSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.watcher.presence 2 | 3 | import com.ofg.infrastructure.discovery.watcher.presence.checker.NoInstancesRunningException 4 | import org.apache.curator.x.discovery.ServiceCache 5 | import org.apache.curator.x.discovery.ServiceInstance 6 | import spock.lang.Specification 7 | 8 | import static org.codehaus.groovy.runtime.StackTraceUtils.extractRootCause 9 | 10 | class DefaultDependencyPresenceOnStartupVerifierSpec extends Specification { 11 | 12 | private static final String SERVICE_NAME = 'service01' 13 | 14 | def 'should throw exception if obligatory dependencies are missing'() { 15 | given: 16 | DefaultDependencyPresenceOnStartupVerifier dependencyVerifier = new DefaultDependencyPresenceOnStartupVerifier() 17 | ServiceCache serviceCache = Mock() 18 | serviceCache.instances >> new ArrayList() 19 | when: 20 | dependencyVerifier.verifyDependencyPresence(SERVICE_NAME, serviceCache, true) 21 | then: 22 | Throwable thrown = thrown(Throwable) 23 | extractRootCause(thrown).class == NoInstancesRunningException 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /micro-deps/micro-deps/src/test/groovy/com/ofg/infrastructure/discovery/watcher/presence/DependencyPresenceOnStartupVerifierSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery.watcher.presence 2 | 3 | import com.ofg.infrastructure.discovery.watcher.presence.checker.PresenceChecker 4 | import org.apache.curator.x.discovery.ServiceCache 5 | import org.apache.curator.x.discovery.ServiceInstance 6 | import spock.lang.Specification 7 | 8 | class DependencyPresenceOnStartupVerifierSpec extends Specification { 9 | 10 | private static final String SERVICE_NAME = 'service01' 11 | 12 | def 'should check optional dependency using optional dependency checker'() { 13 | given: 14 | PresenceChecker optionalDependencyChecker = Mock() 15 | DependencyPresenceOnStartupVerifier dependencyVerifier = new DependencyPresenceOnStartupVerifier(optionalDependencyChecker) { 16 | } 17 | ServiceCache serviceCache = Mock() 18 | serviceCache.instances >> new ArrayList() 19 | when: 20 | dependencyVerifier.verifyDependencyPresence(SERVICE_NAME, serviceCache, false) 21 | then: 22 | 1 * optionalDependencyChecker.checkPresence(SERVICE_NAME, serviceCache.instances) 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /micro-infra-camel/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'Utility controlling presence of correlationId in message flow.' 2 | 3 | ext { 4 | camelVersion = '2.21.0' 5 | } 6 | 7 | dependencies { 8 | compile project(':micro-infra-spring-base') 9 | compile("org.apache.camel:camel-spring-javaconfig:${camelVersion}") { 10 | exclude group: 'org.springframework', module: 'spring-test' 11 | } 12 | 13 | testCompile 'org.spockframework:spock-core' 14 | testRuntime 'org.spockframework:spock-spring' 15 | testCompile 'info.solidsoft.spock:spock-global-unroll' 16 | testCompile 'org.codehaus.groovy:groovy-all' 17 | testCompile "org.apache.camel:camel-test-spring:${camelVersion}" 18 | testCompile 'org.springframework:spring-test' 19 | testCompile 'cglib:cglib-nodep' 20 | testCompile 'org.objenesis:objenesis' 21 | } 22 | -------------------------------------------------------------------------------- /micro-infra-camel/src/main/java/com/ofg/infrastructure/camel/CorrelationIdOnCamelRouteConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.camel; 2 | 3 | import java.util.Random; 4 | 5 | import org.springframework.cloud.sleuth.Tracer; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.context.annotation.EnableAspectJAutoProxy; 9 | 10 | import com.ofg.infrastructure.camel.aspects.CorrelationIdOnCamelRouteAspect; 11 | import com.ofg.infrastructure.web.correlationid.EnableCorrelationId; 12 | 13 | /** 14 | * Configuration that provides {@link CorrelationIdOnCamelRouteAspect}. 15 | */ 16 | @Configuration 17 | @EnableCorrelationId 18 | @EnableAspectJAutoProxy 19 | public class CorrelationIdOnCamelRouteConfiguration { 20 | 21 | @Bean 22 | public CorrelationIdOnCamelRouteAspect correlationIdOnCamelRouteAspect(Random idGenerator, Tracer trace) { 23 | return new CorrelationIdOnCamelRouteAspect(idGenerator, trace); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /micro-infra-camel/src/main/java/com/ofg/infrastructure/camel/EnableCorrelationIdForCamel.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.camel; 2 | 3 | import org.springframework.context.annotation.Import; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | 11 | /** 12 | * Enables Correlation Id for Camel. 13 | * 14 | * @see com.ofg.infrastructure.camel.aspects.CorrelationIdOnCamelRouteAspect 15 | */ 16 | @Target(ElementType.TYPE) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Import(CorrelationIdOnCamelRouteConfiguration.class) 19 | public @interface EnableCorrelationIdForCamel { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /micro-infra-camel/src/test/groovy/com/ofg/infrastructure/camel/CorrelationIdInterceptorSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.camel 2 | 3 | import org.apache.camel.CamelContext 4 | import org.apache.camel.Exchange 5 | import org.apache.camel.impl.DefaultCamelContext 6 | import org.apache.camel.impl.DefaultExchange 7 | import org.springframework.cloud.sleuth.Tracer 8 | import spock.lang.Specification 9 | 10 | import static com.ofg.infrastructure.correlationid.CorrelationIdHolder.CORRELATION_ID_HEADER 11 | 12 | class CorrelationIdInterceptorSpec extends Specification { 13 | 14 | Tracer trace = Stub(Tracer) 15 | 16 | def 'should set new correlationId header in request inbound message if missing'() { 17 | given: 18 | Exchange exchange = defaultExchange() 19 | and: 20 | Random uuidGeneratorMock = Stub(Random) 21 | uuidGeneratorMock.nextLong() >> 42 22 | when: 23 | new CorrelationIdInterceptor(uuidGeneratorMock, trace).process(exchange) 24 | then: 25 | exchange.in.getHeader(CORRELATION_ID_HEADER) == 42 26 | } 27 | 28 | Exchange defaultExchange() { 29 | CamelContext context = new DefaultCamelContext() 30 | return new DefaultExchange(context) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /micro-infra-camel/src/test/groovy/com/ofg/infrastructure/camel/config/CamelRouteAsBeanConfiguration.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.camel.config 2 | 3 | import com.ofg.infrastructure.camel.CorrelationIdOnCamelRouteConfiguration 4 | import org.springframework.context.annotation.Bean 5 | import org.springframework.context.annotation.Configuration 6 | import org.springframework.context.annotation.Import 7 | import org.springframework.context.annotation.ImportResource 8 | 9 | @Configuration 10 | @ImportResource("classpath:spring/camel-context.xml") 11 | @Import(CorrelationIdOnCamelRouteConfiguration.class) 12 | class CamelRouteAsBeanConfiguration { 13 | 14 | @Bean 15 | TestRouteBuilder testRouteBuilder() { 16 | return new TestRouteBuilder() 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /micro-infra-camel/src/test/groovy/com/ofg/infrastructure/camel/config/TestRouteBuilder.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.camel.config 2 | 3 | import groovy.transform.CompileStatic 4 | import org.apache.camel.builder.RouteBuilder 5 | 6 | @CompileStatic 7 | class TestRouteBuilder extends RouteBuilder { 8 | 9 | @Override 10 | void configure() throws Exception { 11 | log.info('Route builder bean configuration...') 12 | from('direct:start').to('mock:result').routeId('route-1') 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /micro-infra-camel/src/test/resources/spring/camel-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/correlationid/CorrelationIdHolder.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.correlationid; 2 | 3 | import org.springframework.cloud.sleuth.Span; 4 | 5 | /** 6 | * Component that stores correlation id using {@link ThreadLocal} 7 | */ 8 | public class CorrelationIdHolder { 9 | public static final String CORRELATION_ID_HEADER = Span.TRACE_ID_NAME; 10 | public static final String OLD_CORRELATION_ID_HEADER = "correlationId"; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/healthcheck/CollaboratorStatus.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.healthcheck; 2 | 3 | public enum CollaboratorStatus { 4 | UP, DOWN; 5 | 6 | public static CollaboratorStatus of(boolean isUp) { 7 | return isUp ? UP : DOWN; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/healthcheck/CollaboratorsConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.healthcheck; 2 | 3 | import com.ofg.infrastructure.discovery.ServiceResolver; 4 | import com.ofg.infrastructure.web.resttemplate.fluent.ServiceRestClient; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * Registers {@link PingController} (the microservice health check controller) and {@link CollaboratorsConnectivityController} (provider of a state of microservice connection with dependent services). 10 | * 11 | * @see PingController 12 | * @see CollaboratorsConnectivityController 13 | */ 14 | @Configuration 15 | public class CollaboratorsConfiguration { 16 | @Bean 17 | public CollaboratorsStatusResolver collaboratorsStatusResolver(ServiceResolver serviceResolver, PingClient pingClient) { 18 | return new CollaboratorsStatusResolver(serviceResolver, pingClient); 19 | } 20 | 21 | @Bean 22 | public PingClient pingClient(ServiceRestClient serviceRestClient) { 23 | return new PingClient(serviceRestClient); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/healthcheck/EnableHealthCheck.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.healthcheck; 2 | 3 | import org.springframework.context.annotation.Import; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Enables support for health checking. 12 | * 13 | * Registers {@link PingController} (the microservice health check controller) and 14 | * {@link CollaboratorsConnectivityController} (provider of a state of microservice connection with dependent services). 15 | * 16 | * @see PingController 17 | * @see CollaboratorsConnectivityController 18 | * @see HealthCheckConfiguration 19 | */ 20 | @Target(ElementType.TYPE) 21 | @Retention(RetentionPolicy.RUNTIME) 22 | @Import(HealthCheckConfiguration.class) 23 | public @interface EnableHealthCheck { 24 | 25 | } 26 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/healthcheck/PingController.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.healthcheck; 2 | 3 | import org.springframework.http.MediaType; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | /** 9 | * {@link RestController} that responds with OK when server is alive 10 | */ 11 | @RestController 12 | public class PingController { 13 | 14 | @RequestMapping(value = "/ping", method = {RequestMethod.GET, RequestMethod.HEAD}, produces = MediaType.TEXT_PLAIN_VALUE) 15 | public String ping() { 16 | return "OK"; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/config/WebInfrastructureConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.config; 2 | 3 | import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.context.annotation.Import; 6 | 7 | import com.ofg.infrastructure.discovery.EnableServiceDiscovery; 8 | import com.ofg.infrastructure.tracing.EnableTracing; 9 | import com.ofg.infrastructure.web.resttemplate.fluent.ServiceRestClientConfiguration; 10 | import com.ofg.infrastructure.web.view.ViewConfiguration; 11 | 12 | /** 13 | * Configuration related to default web application setup. Imports: 14 | *
    15 | *
  • {@link ServiceRestClientConfiguration} - RestTemplate abstraction with ServiceDiscovery
  • 16 | *
  • {@link TraceAutoConfiguration} - adds correlation id to requests
  • 17 | *
  • {@link ViewConfiguration} - converts unmapped views to JSON requests
  • 18 | *
19 | * 20 | * @see ServiceRestClientConfiguration 21 | * @see TraceAutoConfiguration 22 | * @see ViewConfiguration 23 | */ 24 | @Configuration 25 | @EnableServiceDiscovery 26 | @EnableTracing 27 | @Import({ServiceRestClientConfiguration.class, ViewConfiguration.class}) 28 | public class WebInfrastructureConfiguration { 29 | } 30 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/correlationid/EnableCorrelationId.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.correlationid; 2 | 3 | import org.springframework.boot.autoconfigure.ImportAutoConfiguration; 4 | import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; 5 | import org.springframework.cloud.sleuth.log.SleuthLogAutoConfiguration; 6 | 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.RetentionPolicy; 10 | import java.lang.annotation.Target; 11 | 12 | /** 13 | * Enables support for correlation id. 14 | * 15 | * @see org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration 16 | * @see org.springframework.cloud.sleuth.log.SleuthLogAutoConfiguration 17 | * */ 18 | @Target(ElementType.TYPE) 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @ImportAutoConfiguration({TraceAutoConfiguration.class, SleuthLogAutoConfiguration.class}) 21 | public @interface EnableCorrelationId { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/exception/BadParameterError.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.exception; 2 | 3 | public class BadParameterError { 4 | private String field; 5 | private String message; 6 | 7 | public BadParameterError(String field, String message) { 8 | this.field = field; 9 | this.message = message; 10 | } 11 | 12 | public String getField() { 13 | return field; 14 | } 15 | 16 | public void setField(String field) { 17 | this.field = field; 18 | } 19 | 20 | public String getMessage() { 21 | return message; 22 | } 23 | 24 | public void setMessage(String message) { 25 | this.message = message; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/exception/BadParametersException.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.exception; 2 | 3 | import org.springframework.validation.ObjectError; 4 | 5 | import java.util.List; 6 | 7 | public class BadParametersException extends RuntimeException { 8 | private List errors; 9 | 10 | public BadParametersException(List errors) { 11 | this.errors = errors; 12 | } 13 | 14 | public List getErrors() { 15 | return errors; 16 | } 17 | 18 | public void setErrors(List errors) { 19 | this.errors = errors; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/exception/ControllerExceptionConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.exception; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | /** 7 | * Configuration that initializes the {@link ControllerExceptionHandler} as a bean 8 | */ 9 | @Configuration 10 | public class ControllerExceptionConfiguration { 11 | @Bean 12 | public ControllerExceptionHandler controllerExceptionHandler() { 13 | return new ControllerExceptionHandler(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/exception/EnableExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.exception; 2 | 3 | import org.springframework.context.annotation.Import; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Enables support for controller exception handling. 12 | * 13 | * @see com.ofg.infrastructure.web.exception.ControllerExceptionConfiguration 14 | * 15 | */ 16 | @Target(ElementType.TYPE) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Import(ControllerExceptionConfiguration.class) 19 | public @interface EnableExceptionHandler { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/logging/EnableObfuscatedLogging.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging; 2 | 3 | import org.springframework.context.annotation.Import; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Enables support for request body logging. 12 | *

13 | * Configuration that registers a bean that will automatically if DEBUG level of logging is set on 14 | * {@link com.ofg.infrastructure.web.logging.RequestBodyLoggingContextFilter} 15 | * print request body in logs - you can limit its length by setting a property 16 | * 17 | * @see com.ofg.infrastructure.web.logging.RequestLoggingConfiguration 18 | */ 19 | @Target(ElementType.TYPE) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Import(RequestLoggingConfiguration.class) 22 | public @interface EnableObfuscatedLogging {} 23 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/logging/RequestBodyLoggingContextFilter.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging; 2 | 3 | import org.springframework.web.filter.Log4jNestedDiagnosticContextFilter; 4 | 5 | /** 6 | * Filter that logs request body. To enable it apart from registering it as a filter 7 | * you have to set DEBUG level of logging. You can also provide the maximum length 8 | * of the printed payload 9 | * 10 | * @see Log4jNestedDiagnosticContextFilter 11 | */ 12 | public class RequestBodyLoggingContextFilter extends Log4jNestedDiagnosticContextFilter { 13 | public RequestBodyLoggingContextFilter(int maxPayloadLength) { 14 | this.setIncludePayload(true); 15 | this.setMaxPayloadLength(maxPayloadLength); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/logging/feign/SleuthRequestIdProvider.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging.feign; 2 | 3 | 4 | import com.ofg.infrastructure.web.logging.RequestIdProvider; 5 | import org.springframework.cloud.sleuth.SpanAccessor; 6 | 7 | public class SleuthRequestIdProvider implements RequestIdProvider { 8 | 9 | private final SpanAccessor spanAccessor; 10 | 11 | public SleuthRequestIdProvider(SpanAccessor spanAccessor) { 12 | this.spanAccessor = spanAccessor; 13 | } 14 | 15 | @Override 16 | public String getRequestId() { 17 | return spanAccessor.getCurrentSpan() != null ? 18 | String.valueOf(spanAccessor.getCurrentSpan().getSpanId()) : "_MISSING_SPAN_ID"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/custom/HttpStatusVerifier.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.custom 2 | 3 | import groovy.transform.CompileStatic 4 | import org.springframework.http.HttpStatus 5 | 6 | @CompileStatic 7 | class HttpStatusVerifier { 8 | /** 9 | * Verifies whether the passed {@link HttpStatus} is either client or server error 10 | * 11 | * @param status 12 | * @return 13 | */ 14 | public static boolean isError(HttpStatus status) { 15 | return status.series() in [HttpStatus.Series.CLIENT_ERROR, HttpStatus.Series.SERVER_ERROR] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/custom/InputStreamPrinter.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.custom 2 | 3 | import com.google.common.base.Charsets 4 | import com.google.common.io.ByteStreams 5 | import org.apache.commons.lang.StringUtils 6 | 7 | 8 | class InputStreamPrinter { 9 | 10 | static String abbreviate(InputStream inputStream, int maxBytes) { 11 | final InputStream truncated = ByteStreams.limit(inputStream, maxBytes + 1) 12 | final byte[] responseBytes = ByteStreams.toByteArray(truncated) 13 | final String responseAsString = new String(responseBytes, Charsets.UTF_8) 14 | return StringUtils.abbreviate(responseAsString, Math.max(maxBytes, 4)) 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/custom/ResponseException.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.custom 2 | 3 | import groovy.transform.CompileStatic 4 | import groovy.transform.InheritConstructors 5 | import org.springframework.http.HttpHeaders 6 | import org.springframework.http.HttpStatus 7 | 8 | @CompileStatic 9 | class ResponseException extends RuntimeException { 10 | 11 | final HttpStatus httpStatus 12 | final HttpHeaders headers 13 | final String body 14 | 15 | ResponseException(HttpStatus httpStatus, String body, HttpHeaders headers) { 16 | this.httpStatus = httpStatus 17 | this.body = body 18 | this.headers = headers 19 | } 20 | 21 | String getMessage() { 22 | return "Status code: [$httpStatus], Headers: [$headers], Body: [$body]"; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/AbstractMethodBuilder.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent 2 | 3 | import org.apache.commons.lang.StringUtils 4 | 5 | class AbstractMethodBuilder { 6 | protected final Map params = [:] 7 | 8 | protected def replaceFirstPlaceholderWithValue() { 9 | final String template = params.urlTemplate 10 | final String skippedFirstPlaceholder = StringUtils.substringAfter(template, '}') 11 | final Object[] variables = params.urlVariablesArray 12 | params.urlTemplate = variables.head() + skippedFirstPlaceholder 13 | params.urlVariablesArray = variables.tail() 14 | } 15 | 16 | protected boolean templateStartsWithPlaceholder() { 17 | return params.urlTemplate.startsWith('{') 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/EnableServiceRestClient.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent; 2 | 3 | import org.springframework.context.annotation.Import; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Enables support for ServiceRestClient that will take care of everything for you and gives you a fluent interface to 12 | * achieve that. 13 | * 14 | * Creates a bean of abstraction over {@link org.springframework.web.client.RestOperations}. 15 | * 16 | * @see ServiceRestClient 17 | * @see ServiceRestClientConfiguration 18 | */ 19 | @Target(ElementType.TYPE) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Import(ServiceRestClientConfiguration.class) 22 | public @interface EnableServiceRestClient { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/HTTPAuthorizationUtils.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent 2 | 3 | import groovy.transform.CompileStatic 4 | import org.apache.commons.codec.binary.Base64 5 | 6 | import static java.nio.charset.StandardCharsets.US_ASCII 7 | 8 | @CompileStatic 9 | class HTTPAuthorizationUtils { 10 | 11 | /** 12 | * Encodes credentials for HTTP basic authentication 13 | */ 14 | public static String encodeCredentials(String username, String password) { 15 | String plainCreds = username + ":" + password 16 | byte[] plainCredsBytes = plainCreds.getBytes(US_ASCII) 17 | byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes) 18 | return new String(base64CredsBytes) 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/request/ParametrizedUrlHavingWith.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.request 2 | 3 | /** 4 | * Interface for urls that consist of variables 5 | */ 6 | interface ParametrizedUrlHavingWith { 7 | 8 | /** 9 | * 10 | * @param urlVariables - variables passed as an array 11 | */ 12 | T withVariables(Object... urlVariables) 13 | 14 | /** 15 | * 16 | * @param urlVariables - variables passed as a key, 17 | * value pair where key is the param name and value is its value 18 | */ 19 | T withVariables(Map urlVariables) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/request/RequestHaving.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.request 2 | 3 | /** 4 | * Interface for HttpMethods that can have requests consisting of a body 5 | */ 6 | interface RequestHaving { 7 | 8 | /** 9 | * 10 | * @param request - body of the request 11 | */ 12 | T body(Object request) 13 | 14 | /** 15 | * Use this method if you don't want to provide a body of the request 16 | */ 17 | T withoutBody() 18 | 19 | } 20 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/executor/Executable.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor 2 | 3 | /** 4 | * Interface that gives a nice DSL 5 | */ 6 | interface Executable { 7 | T andExecuteFor() 8 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/executor/InvalidHttpMethodParametersException.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class InvalidHttpMethodParametersException extends RuntimeException { 7 | InvalidHttpMethodParametersException(Map params) { 8 | super("Invalid args [$params] passed to method") 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/executor/LocationReceiving.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor 2 | 3 | import com.google.common.util.concurrent.ListenableFuture 4 | 5 | 6 | /** 7 | * Interface for HttpMethods that can return location from Http headers. 8 | * It's a helper interface since you can always retrieve location from the 9 | * {@link org.springframework.http.ResponseEntity}. 10 | */ 11 | interface LocationReceiving { 12 | 13 | URI forLocation() 14 | ListenableFuture forLocationAsync() 15 | 16 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/BodyContainingWithHeaders.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | /** 6 | * Abstraction over {@link WithHeaders} with explicitly provided type {@link ResponseReceiving} 7 | * so that the compiler resolves types properly 8 | */ 9 | @CompileStatic 10 | class BodyContainingWithHeaders extends WithHeaders { 11 | BodyContainingWithHeaders(T parent, Map params, PredefinedHttpHeaders predefinedHeaders) { 12 | super(parent, params, predefinedHeaders) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/BodyContainingWithQueryParameters.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive 2 | 3 | class BodyContainingWithQueryParameters extends WithQueryParameters { 4 | BodyContainingWithQueryParameters(T parent, Map params) { 5 | super(parent, params) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/BodylessWithHeaders.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class BodylessWithHeaders extends WithHeaders { 7 | BodylessWithHeaders(T parent, Map params, PredefinedHttpHeaders predefinedHeaders) { 8 | super(parent, params, predefinedHeaders) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/BodylessWithQueryParameters.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class BodylessWithQueryParameters extends WithQueryParameters { 7 | BodylessWithQueryParameters(T parent, Map params) { 8 | super(parent, params) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/HeadersHaving.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive; 2 | 3 | /** 4 | * Interface for HttpMethods that can have headers set on its requests 5 | */ 6 | public interface HeadersHaving { 7 | HeadersSetting withHeaders(); 8 | } 9 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/HttpEntitySending.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive 2 | 3 | import org.springframework.http.HttpEntity 4 | 5 | /** 6 | * Interface that allows sending a request from a {@link HttpEntity} 7 | */ 8 | interface HttpEntitySending { 9 | T httpEntity(HttpEntity httpEntity) 10 | 11 | T withQueryParameters(Map queryParametersMap) 12 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/ObjectReceiving.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive 2 | 3 | import com.google.common.util.concurrent.ListenableFuture 4 | 5 | 6 | /** 7 | * Interface that defines what is the type of the received response. 8 | * It will return an object of provided class. 9 | */ 10 | interface ObjectReceiving { 11 | 12 | public T ofType(Class responseType) 13 | 14 | public ListenableFuture ofTypeAsync(Class responseType) 15 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/QueryParametersHaving.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive; 2 | 3 | /** 4 | * Interface for HttpMethods that can have query parameters set on its requests 5 | */ 6 | public interface QueryParametersHaving { 7 | QueryParametersSetting withQueryParameters(); 8 | } 9 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/ResponseEntityReceiving.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive 2 | 3 | import com.google.common.util.concurrent.ListenableFuture 4 | import org.springframework.http.ResponseEntity 5 | 6 | /** 7 | * Interface that defines what is the type of the received response. 8 | * It will return a {@link ResponseEntity} of the provided class. 9 | */ 10 | interface ResponseEntityReceiving { 11 | public ListenableFuture> ofTypeAsync(Class responseType) 12 | public ResponseEntity ofType(Class responseType) 13 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/ResponseExtracting.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive 2 | 3 | /** 4 | * Interface allowing to retrieve a response in a form of an object or 5 | * a {@link org.springframework.http.ResponseEntity}. You can also choose 6 | * to ignore the received response. 7 | * 8 | * @see ObjectReceiving 9 | * @see ResponseEntityReceiving 10 | * @see ResponseIgnoring 11 | */ 12 | interface ResponseExtracting extends ResponseIgnoring { 13 | 14 | ObjectReceiving anObject() 15 | 16 | ResponseEntityReceiving aResponseEntity() 17 | 18 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/ResponseIgnoring.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive 2 | 3 | import com.google.common.util.concurrent.ListenableFuture 4 | 5 | interface ResponseIgnoring { 6 | /** 7 | * When you do not care about the received response for your HTTP request 8 | */ 9 | void ignoringResponse() 10 | ListenableFuture ignoringResponseAsync() 11 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/ResponseReceiving.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive 2 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor.Executable 3 | 4 | /** 5 | * Interface that is a base for all the HttpMethods 6 | */ 7 | interface ResponseReceiving extends HeadersHaving, QueryParametersHaving, Executable, ResponseExtracting { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/config/RestClientConfigurer.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.config 2 | 3 | import org.springframework.http.client.SimpleClientHttpRequestFactory 4 | 5 | /** 6 | * Convenient way to configure RestClient default params. 7 | * @see {@link ServiceRestClientConfigurer } 8 | * 9 | * @since 0.8.17 10 | */ 11 | class RestClientConfigurer { 12 | SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory() 13 | Integer maxLogResponseChars = 4096 14 | 15 | RestClientConfigurer readTimeout(Integer readTimeout) { 16 | if (readTimeout != null) { 17 | this.requestFactory.readTimeout = readTimeout 18 | } 19 | return this 20 | } 21 | 22 | RestClientConfigurer connectTimeout(Integer connectTimeout) { 23 | if (connectTimeout != null) { 24 | this.requestFactory.connectTimeout = connectTimeout 25 | } 26 | return this 27 | } 28 | 29 | RestClientConfigurer maxLogResponseChars(Integer maxLogResponseChars) { 30 | if (maxLogResponseChars != null) { 31 | this.maxLogResponseChars = maxLogResponseChars 32 | } 33 | return this 34 | } 35 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/config/ServiceRestClientConfigurer.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.config 2 | 3 | import org.springframework.http.converter.HttpMessageConverter 4 | 5 | /** 6 | * Interface to be implemented by Spring beans willing to provide their own configuration for 7 | * {@link com.ofg.infrastructure.web.resttemplate.fluent.ServiceRestClientConfiguration ServiceRestClientConfiguration}. 8 | * 9 | *

Consider using {@link com.ofg.infrastructure.web.resttemplate.fluent.config.ServiceRestClientConfigurerAdapter ServiceRestClientConfigurerAdapter} 10 | * providing default implementations for all components. Only custom configuration needs to be overridden. Furthermore, backward compatibility 11 | * of this interface will be insured in case new customization options are introduced in the future. 12 | * 13 | *

See {@link com.ofg.infrastructure.web.resttemplate.fluent.ServiceRestClientConfiguration ServiceRestClientConfiguration}. 14 | * 15 | * @since 0.8.17 16 | */ 17 | interface ServiceRestClientConfigurer { 18 | 19 | void configureMessageConverters(List> converters); 20 | 21 | void configureRestClientParams(RestClientConfigurer configurer); 22 | } 23 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/config/ServiceRestClientConfigurerAdapter.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.config 2 | 3 | import groovy.transform.CompileStatic 4 | import org.springframework.http.converter.HttpMessageConverter 5 | 6 | /** 7 | * A convenience {@link com.ofg.infrastructure.web.resttemplate.fluent.config.ServiceRestClientConfigurer ServiceRestClientConfigurer} that 8 | * have empty methods to override. 9 | * 10 | * @since 0.8.17 11 | */ 12 | @CompileStatic 13 | class ServiceRestClientConfigurerAdapter implements ServiceRestClientConfigurer { 14 | 15 | @Override 16 | void configureMessageConverters(List> converters) { 17 | } 18 | 19 | @Override 20 | void configureRestClientParams(RestClientConfigurer configurer) { 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/delete/DeleteMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.delete 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.request.HttpMethod 4 | 5 | /** 6 | * {@link org.springframework.http.HttpMethod#DELETE} method base interface 7 | * 8 | * Sample execution for a {@link org.springframework.http.ResponseEntity}: 9 | * 10 | *

11 |  * httpMethodBuilder
12 |  *    .delete()
13 |  *        .onUrl("client/123123")
14 |  *    .andExecuteFor()
15 |  *        .aResponseEntity()
16 |  * 
17 | * 18 | * Sample execution with headers ignoring response: 19 | * 20 | *
21 |  * httpMethodBuilder
22 |  *    .delete()
23 |  *    .onUrl("client/123123")
24 |  *    .withHeaders()
25 |  *        .contentTypeJson()
26 |  *    .andExecuteFor()
27 |  *        .ignoringResponse()
28 |  * 
29 | * 30 | * @see com.ofg.infrastructure.web.resttemplate.fluent.HttpMethodBuilder 31 | * @see HttpMethod 32 | * @see ResponseReceivingDeleteMethod 33 | * @see UrlParameterizableDeleteMethod 34 | */ 35 | interface DeleteMethod extends HttpMethod { 36 | 37 | } 38 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/delete/ResponseReceivingDeleteMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.delete 2 | 3 | import com.google.common.util.concurrent.ListenableFuture 4 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor.Executable 5 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.HeadersHaving 6 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.HttpEntitySending 7 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.ResponseIgnoring 8 | import org.springframework.http.ResponseEntity 9 | 10 | /** 11 | * {@link org.springframework.http.HttpMethod#DELETE} method doesn't have a response 12 | * so this interface provides only a {@link ResponseEntity} result or {@link ResponseIgnoring} one 13 | */ 14 | interface ResponseReceivingDeleteMethod extends 15 | HeadersHaving, Executable, 16 | HttpEntitySending, ResponseIgnoring { 17 | 18 | ResponseEntity aResponseEntity() 19 | ListenableFuture aResponseEntityAsync() 20 | 21 | } 22 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/delete/UrlParameterizableDeleteMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.delete 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.request.ParametrizedUrlHavingWith 4 | 5 | /** 6 | * {@link org.springframework.http.HttpMethod#DELETE} methods can have its headers parametrized 7 | */ 8 | interface UrlParameterizableDeleteMethod extends ParametrizedUrlHavingWith { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/get/ResponseReceivingGetMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.get 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.HttpEntitySending 4 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.ResponseReceiving 5 | /** 6 | * {@link org.springframework.http.HttpMethod#GET} method allows receiving requests with body what 7 | * {@link ResponseReceiving} interface provides. 8 | */ 9 | interface ResponseReceivingGetMethod extends ResponseReceiving, HttpEntitySending{ 10 | } 11 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/get/UrlParameterizableGetMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.get 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.request.ParametrizedUrlHavingWith 4 | 5 | interface UrlParameterizableGetMethod extends ParametrizedUrlHavingWith { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/head/ResponseReceivingHeadMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.head 2 | 3 | import com.google.common.util.concurrent.ListenableFuture 4 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor.Executable 5 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.HeadersHaving 6 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.HttpEntitySending 7 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.ResponseIgnoring 8 | import org.springframework.http.HttpHeaders 9 | import org.springframework.http.ResponseEntity 10 | 11 | /** 12 | * {@link org.springframework.http.HttpMethod#HEAD} method doesn't have a response 13 | * so this interface provides a {@link ResponseEntity} result or {@link HttpHeaders} to get headers 14 | */ 15 | interface ResponseReceivingHeadMethod extends 16 | HeadersHaving, Executable, 17 | HttpEntitySending, ResponseIgnoring { 18 | 19 | ResponseEntity aResponseEntity() 20 | ListenableFuture aResponseEntityAsync() 21 | 22 | HttpHeaders httpHeaders() 23 | ListenableFuture httpHeadersAsync() 24 | } 25 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/head/UrlParameterizableHeadMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.head 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.request.ParametrizedUrlHavingWith 4 | 5 | interface UrlParameterizableHeadMethod extends ParametrizedUrlHavingWith { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/options/AllowContainingWithHeaders.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.options 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.PredefinedHttpHeaders 4 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.WithHeaders 5 | import groovy.transform.CompileStatic 6 | 7 | /** 8 | * Class that provides explicit types for the {@link WithHeaders} so that the compiler 9 | * know what the types it should return 10 | */ 11 | @CompileStatic 12 | class AllowContainingWithHeaders extends WithHeaders { 13 | AllowContainingWithHeaders(ResponseReceivingOptionsMethod parent, Map params, PredefinedHttpHeaders predefinedHeaders) { 14 | super(parent, params, predefinedHeaders) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/options/AllowHeaderReceiving.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.options 2 | 3 | import com.google.common.util.concurrent.ListenableFuture 4 | import org.springframework.http.HttpMethod 5 | 6 | /** 7 | * {@link HttpMethod#HEAD} is closely related to retrieving the {@link org.springframework.http.HttpHeaders#ALLOW} 8 | * request header. This interface provides an easy way to retrieve it. 9 | */ 10 | interface AllowHeaderReceiving { 11 | 12 | /** 13 | * 14 | * @return - a set of values from the {@link org.springframework.http.HttpHeaders#ALLOW} header 15 | */ 16 | Set allow() 17 | 18 | ListenableFuture> allowAsync() 19 | 20 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/options/ResponseReceivingOptionsMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.options 2 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor.Executable 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.HeadersHaving 4 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.HttpEntitySending 5 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.ResponseExtracting 6 | 7 | /** 8 | * {@link org.springframework.http.HttpMethod#OPTIONS} HTTP method allows receiving requests with body what 9 | * {@link com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.ResponseExtracting} interface provides. 10 | * Additionally it gives the possibility to easily retrieve the {@link org.springframework.http.HttpHeaders#ALLOW} 11 | * header via {@link AllowHeaderReceiving} interface. 12 | */ 13 | interface ResponseReceivingOptionsMethod extends 14 | HeadersHaving, ResponseExtracting, AllowHeaderReceiving, 15 | Executable, HttpEntitySending { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/options/UrlParameterizableOptionsMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.options 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.request.ParametrizedUrlHavingWith 4 | 5 | interface UrlParameterizableOptionsMethod extends ParametrizedUrlHavingWith { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/post/RequestHavingPostMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.post 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.request.RequestHaving 4 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.HttpEntitySending 5 | 6 | /** 7 | * Base interface for {@link org.springframework.http.HttpMethod#POST} HTTP method in terms 8 | * of sending a request 9 | * 10 | * @see ResponseReceivingPostMethod 11 | */ 12 | interface RequestHavingPostMethod extends RequestHaving, HttpEntitySending { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/post/ResponseReceivingPostMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.post 2 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor.LocationReceiving 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.ResponseReceiving 4 | 5 | /** 6 | * The {@link org.springframework.http.HttpMethod#POST} HTTP method can send a message with a body 7 | * and can post for location. 8 | * 9 | * @see ResponseReceiving 10 | * @see LocationReceiving 11 | */ 12 | interface ResponseReceivingPostMethod extends ResponseReceiving, LocationReceiving { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/post/UrlParameterizablePostMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.post 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.request.ParametrizedUrlHavingWith 4 | 5 | interface UrlParameterizablePostMethod extends ParametrizedUrlHavingWith { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/put/RequestHavingPutMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.put 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.request.RequestHaving 4 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.HttpEntitySending 5 | 6 | /** 7 | * Base interface for {@link org.springframework.http.HttpMethod#PUT} HTTP method in terms 8 | * of sending a request 9 | * 10 | * @see RequestHaving 11 | * @see HttpEntitySending 12 | */ 13 | interface RequestHavingPutMethod extends RequestHaving, HttpEntitySending { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/put/ResponseReceivingPutMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.put 2 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor.LocationReceiving 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.HttpEntitySending 4 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive.ResponseReceiving 5 | 6 | /** 7 | * The {@link org.springframework.http.HttpMethod#POST} HTTP method can send a message with a body 8 | * and can put for location. 9 | * 10 | * @see ResponseReceiving 11 | * @see LocationReceiving 12 | * @see HttpEntitySending 13 | */ 14 | interface ResponseReceivingPutMethod extends ResponseReceiving, LocationReceiving, HttpEntitySending { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/resttemplate/fluent/put/UrlParameterizablePutMethod.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.put 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.request.ParametrizedUrlHavingWith 4 | 5 | interface UrlParameterizablePutMethod extends ParametrizedUrlHavingWith { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/groovy/com/ofg/infrastructure/web/view/EnableJSONViewResolver.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.view; 2 | 3 | import org.springframework.context.annotation.Import; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Enables JSON serialization for objects returned by controllers' methods. 12 | * 13 | * Pretty printing setting is based on active profile: 14 | * - in production environment pretty printing is set to false, 15 | * - in test or development environment pretty printing is set to true. 16 | * 17 | * @see com.ofg.infrastructure.web.view.ViewConfiguration 18 | */ 19 | @Target(ElementType.TYPE) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Import(ViewConfiguration.class) 22 | public @interface EnableJSONViewResolver { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/discovery/EnableServiceDiscovery.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | import org.springframework.context.annotation.Import; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Enables support for service discovery 12 | * 13 | * @see com.ofg.infrastructure.discovery.ServiceDiscoveryConfiguration 14 | */ 15 | @Target(ElementType.TYPE) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Import(ServiceDiscoveryConfiguration.class) 18 | public @interface EnableServiceDiscovery { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/discovery/ServiceDiscoveryConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.discovery; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.context.annotation.Import; 5 | 6 | /** 7 | * This configuration imports configurations related to service discovery 8 | * 9 | * @see ServiceResolverConfiguration 10 | */ 11 | @Configuration 12 | @Import(ServiceResolverConfiguration.class) 13 | public class ServiceDiscoveryConfiguration { 14 | } 15 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/hystrix/EnableHystrixServlet.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.hystrix; 2 | 3 | import org.springframework.context.annotation.Import; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Enables support for a servlet emitting Hystrix data 12 | * 13 | * @see HystrixServletConfiguration 14 | * 15 | */ 16 | @Target(ElementType.TYPE) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Import(HystrixServletConfiguration.class) 19 | public @interface EnableHystrixServlet { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/hystrix/HystrixServletConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.hystrix; 2 | 3 | import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.boot.web.servlet.ServletRegistrationBean; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Conditional; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * Registers a servlet that will be streaming Hystrix data 12 | * 13 | * @see HystrixMetricsStreamServlet 14 | */ 15 | @Configuration 16 | @Conditional(IsHystrixServletEnabled.class) 17 | public class HystrixServletConfiguration { 18 | @Bean 19 | public ServletRegistrationBean servletRegistrationBean(@Value("${hystrix.stream-servlet.path:/health/hystrix.stream}") String hystrixMetricsStreamPath) { 20 | return new ServletRegistrationBean(new HystrixMetricsStreamServlet(), hystrixMetricsStreamPath); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/hystrix/IsHystrixServletEnabled.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.hystrix; 2 | 3 | import com.ofg.infrastructure.config.PropertyAbsentOrEnabledCondition; 4 | 5 | /** 6 | * Checks for the presence of the property to verify whether Hystrix is enabled or not 7 | */ 8 | class IsHystrixServletEnabled extends PropertyAbsentOrEnabledCondition { 9 | 10 | private static final String HYSTRIX_SERVLET_ENABLED = "com.ofg.infra.microservice.hystrix.servlet"; 11 | 12 | public IsHystrixServletEnabled() { 13 | super(HYSTRIX_SERVLET_ENABLED); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/metrics/config/EnableMetrics.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.metrics.config; 2 | 3 | import org.springframework.context.annotation.Import; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Enables support for registering metric related Spring beans. 12 | * 13 | * For production use it registers publishing to JMX and Graphite. 14 | * For development use it only registers publishing to JMX. 15 | * 16 | * @see com.ofg.infrastructure.metrics.config.MetricsConfiguration 17 | * @see com.codahale.metrics.MetricRegistry 18 | * 19 | */ 20 | @Target(ElementType.TYPE) 21 | @Retention(RetentionPolicy.RUNTIME) 22 | @Import(MetricsConfiguration.class) 23 | public @interface EnableMetrics { 24 | 25 | } 26 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/metrics/config/GraphiteFormat.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.metrics.config; 2 | 3 | public enum GraphiteFormat { 4 | UDP, TCP, PICKLE 5 | } 6 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/metrics/config/IsGraphitePublishingEnabled.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.metrics.config; 2 | 3 | import com.ofg.infrastructure.config.PropertyAbsentOrEnabledCondition; 4 | 5 | 6 | public class IsGraphitePublishingEnabled extends PropertyAbsentOrEnabledCondition { 7 | 8 | public static final String GRAPHITE_PUBLISHING = "graphite.publishing.enabled"; 9 | 10 | public IsGraphitePublishingEnabled() { 11 | super(GRAPHITE_PUBLISHING); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/metrics/publishing/EnvironmentAwareMetricsBasePath.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.metrics.publishing; 2 | 3 | import com.google.common.base.Joiner; 4 | 5 | /** 6 | * Builds metrics base path starting with root name followed by environment, country, application and node. 7 | * All mentioned path components are concatenated with periods and dots in node are replaced with underscores 8 | */ 9 | public class EnvironmentAwareMetricsBasePath implements MetricsBasePath { 10 | 11 | private final String path; 12 | 13 | public EnvironmentAwareMetricsBasePath(String rootName, String environment, String country, String application, String node) { 14 | path = Joiner.on(".").join(rootName, environment, country, application, replaceDots(node)); 15 | } 16 | 17 | @Override 18 | public String getPath() { 19 | return path; 20 | } 21 | 22 | private String replaceDots(String name) { 23 | return name.replace(".", "_"); 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return path; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/metrics/publishing/MetricsBasePath.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.metrics.publishing; 2 | 3 | /** 4 | * Provides metrics base path for publishing purposes. 5 | * MetricsBasePath is intended to be used when publishing metrics to remote servers to distinguish metrics published from multiple sources. 6 | */ 7 | public interface MetricsBasePath { 8 | 9 | String getPath(); 10 | } 11 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/metrics/publishing/MetricsPublishing.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.metrics.publishing; 2 | 3 | /** 4 | * Interface for metrics publishing. 5 | *

6 | * You can publish metrics to different places including those predefined: 7 | *

    8 | *
  • Console - ConsoleReporter (com.codahale.metrics)
  • 9 | *
  • Slf4j - Slf4jReporter (com.codahale.metrics)
  • 10 | *
  • Csv - CsvReporter (com.codahale.metrics)
  • 11 | *
  • Graphite - GraphiteReporter (com.codahale.metrics.graphite)
  • 12 | *
  • Jmx - JmxReporter (com.codahale.metrics)
  • 13 | *
14 | *

15 | * as well as your own custom ones. 16 | */ 17 | public interface MetricsPublishing { 18 | /** 19 | * Starts metrics publishing 20 | */ 21 | void start(); 22 | 23 | /** 24 | * Stops metrics publishing 25 | */ 26 | void stop(); 27 | } 28 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/metrics/publishing/OutputDirectoryDoesNotExists.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.metrics.publishing; 2 | 3 | import java.io.File; 4 | 5 | public class OutputDirectoryDoesNotExists extends RuntimeException { 6 | 7 | public OutputDirectoryDoesNotExists(File directory) { 8 | super(directory.getName() + " directory does not exists"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/metrics/publishing/PublishingInterval.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.metrics.publishing; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class PublishingInterval { 6 | 7 | private final long interval; 8 | private final TimeUnit timeUnit; 9 | 10 | /** 11 | * Defines publishing interval for metrics publisher 12 | * 13 | * @param interval - amount of time between publications 14 | * @param timeUnit - time unit for {@code interval} 15 | */ 16 | public PublishingInterval(long interval, TimeUnit timeUnit) { 17 | this.interval = interval; 18 | this.timeUnit = timeUnit; 19 | } 20 | 21 | public final long getInterval() { 22 | return interval; 23 | } 24 | 25 | public final TimeUnit getTimeUnit() { 26 | return timeUnit; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/tracing/EnableTracing.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.tracing; 2 | 3 | import org.springframework.context.annotation.Import; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Enables support for the tracing modules basing on Spring Cloud Sleuth. 12 | * 13 | * Imports: 14 | *

    15 | *
  • {@link com.ofg.infrastructure.tracing.TracingConfiguration} - contains configurations related to tracing
  • 16 | *
17 | * 18 | * @see com.ofg.infrastructure.tracing.TracingConfiguration 19 | */ 20 | @Target(ElementType.TYPE) 21 | @Retention(RetentionPolicy.RUNTIME) 22 | @Import(TracingConfiguration.class) 23 | public @interface EnableTracing { 24 | } 25 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/tracing/TracingConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.tracing; 2 | 3 | import org.springframework.boot.autoconfigure.AutoConfigureOrder; 4 | import org.springframework.cloud.sleuth.Sampler; 5 | import org.springframework.cloud.sleuth.sampler.AlwaysSampler; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.core.Ordered; 9 | 10 | @Configuration 11 | @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) 12 | public class TracingConfiguration { 13 | 14 | @Bean 15 | public Sampler alwaysSampler() { 16 | return new AlwaysSampler(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/web/WebConsts.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | public class WebConsts { 6 | private WebConsts() {} 7 | public static final String DEFAULT_SKIP_PATTERN_STRING = "/api-docs.*|/fonts.*|/autoconfig|/configprops|/dump|/info|/metrics.*|/mappings|/trace|/health|/ping|/swagger.*|.*\\.png|.*\\.ico|.*\\.css|.*\\.js|.*\\.html"; 8 | public static final Pattern DEFAULT_SKIP_PATTERN = Pattern.compile(DEFAULT_SKIP_PATTERN_STRING); 9 | } 10 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/web/logging/RequestDataProvider.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging; 2 | 3 | import static java.util.concurrent.TimeUnit.MILLISECONDS; 4 | 5 | import com.google.common.cache.Cache; 6 | import com.google.common.cache.CacheBuilder; 7 | 8 | public class RequestDataProvider { 9 | 10 | private Cache storage; 11 | 12 | public RequestDataProvider(int timeToLiveMillis) { 13 | storage = CacheBuilder.newBuilder().expireAfterWrite(timeToLiveMillis, MILLISECONDS).build(); 14 | } 15 | 16 | public void store(String requestId, HttpData data) { 17 | storage.put(requestId, data); 18 | } 19 | 20 | public HttpData retrieve(String requestId) { 21 | return storage.getIfPresent(requestId); 22 | } 23 | 24 | public void remove(String requestId) { 25 | storage.invalidate(requestId); 26 | } 27 | 28 | public long size() { 29 | return storage.size(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/web/logging/RequestIdProvider.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging; 2 | 3 | public interface RequestIdProvider { 4 | String getRequestId(); 5 | } 6 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/web/logging/obfuscation/FieldReplacementStrategy.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging.obfuscation; 2 | 3 | public class FieldReplacementStrategy implements ObfuscationFieldStrategy { 4 | 5 | @Override 6 | public String obfuscate(String fieldToObfuscate) { 7 | return "REMOVED"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/web/logging/obfuscation/ObfuscationFieldStrategy.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging.obfuscation; 2 | 3 | public interface ObfuscationFieldStrategy { 4 | 5 | String obfuscate(String fieldToObfuscate); 6 | 7 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/web/logging/obfuscation/PayloadObfuscationProcessor.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging.obfuscation; 2 | 3 | import com.google.common.base.Predicate; 4 | import com.google.common.collect.Iterables; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public class PayloadObfuscationProcessor { 10 | 11 | private final List obfuscatorList; 12 | 13 | public PayloadObfuscationProcessor(List obfuscatorList) { 14 | this.obfuscatorList = obfuscatorList; 15 | } 16 | 17 | public String process(String content, final Map headers, List fieldsToObfuscate) { 18 | Iterable obfuscators = Iterables.filter(obfuscatorList, new Predicate() { 19 | public boolean apply(AbstractPayloadObfuscator obfuscator) { 20 | return obfuscator.isApplicable(headers); 21 | } 22 | }); 23 | if(obfuscators == null || !obfuscators.iterator().hasNext()){ 24 | return content; 25 | }else{ 26 | for(AbstractPayloadObfuscator obfuscator : obfuscators){ 27 | content = obfuscator.process(content.replace("\n", ""), fieldsToObfuscate); 28 | } 29 | return content; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/web/logging/wrapper/HttpServletResponseLoggingWrapper.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging.wrapper; 2 | 3 | import javax.servlet.ServletOutputStream; 4 | import javax.servlet.http.HttpServletResponse; 5 | import javax.servlet.http.HttpServletResponseWrapper; 6 | import java.io.IOException; 7 | 8 | public class HttpServletResponseLoggingWrapper extends HttpServletResponseWrapper { 9 | 10 | private final DelegatingServletOutputStream delegate; 11 | 12 | public HttpServletResponseLoggingWrapper(HttpServletResponse response) { 13 | super(response); 14 | this.delegate = new DelegatingServletOutputStream(initDelegateInputStream()); 15 | } 16 | 17 | private ServletOutputStream initDelegateInputStream() { 18 | try { 19 | return super.getOutputStream(); 20 | } catch (IOException e) { 21 | throw new IllegalStateException("Error", e); 22 | } 23 | } 24 | 25 | @Override 26 | public ServletOutputStream getOutputStream() throws IOException { 27 | return this.delegate; 28 | } 29 | 30 | public byte[] getBytes() { 31 | return this.delegate.getBytes(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/web/resttemplate/fluent/TracingInfo.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent; 2 | 3 | import org.springframework.cloud.sleuth.TraceKeys; 4 | import org.springframework.cloud.sleuth.Tracer; 5 | 6 | /** 7 | * Wrapper class to easy pass through constructors. 8 | * Adds tracing capabilities to fluent api. 9 | */ 10 | public class TracingInfo { 11 | 12 | private final Tracer tracer; 13 | private final TraceKeys traceKeys; 14 | 15 | public TracingInfo(Tracer tracer, TraceKeys traceKeys) { 16 | this.tracer = tracer; 17 | this.traceKeys = traceKeys; 18 | } 19 | 20 | public Tracer getTracer() { 21 | return tracer; 22 | } 23 | 24 | public TraceKeys getTraceKeys() { 25 | return traceKeys; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/web/resttemplate/fluent/URIMetricNamer.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent; 2 | 3 | import java.net.URI; 4 | 5 | /** 6 | * A strategy for inventing (parts of) metric names for metrics relating to {@link java.net.URI}-s. 7 | *

8 | * The purpose of this interface is to allow the Users to elide any dynamic parts of the URI from the metric name 9 | * or - more generally - allow the Users to fine-tune the granularity of metric names used by the 10 | * {@link com.ofg.infrastructure.web.resttemplate.RestOperationsMetricsAspect}. Therefore, in most cases 11 | * implementations should elide any path- and uri- parameters found in the given URIs, as well as any other parts 12 | * that might lead to a situation where the set of possible names returned by the implementation in a given application 13 | * is unbounded. 14 | *

15 | * Returned metric names may only consist of: latin alphanumerics, dots, and underscores. 16 | * The returned names must not start with a dot. 17 | */ 18 | public interface URIMetricNamer { 19 | String metricNameFor(URI uri); 20 | } 21 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/ParametersSetting.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive; 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor.Executable; 4 | 5 | /** 6 | * Interface that provides methods to set parameters on HTTP GET requests 7 | * 8 | * @param < T > - interface to return via {@link Executable} when you have finished setting headers 9 | */ 10 | public interface ParametersSetting extends Executable { 11 | } 12 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/java/com/ofg/infrastructure/web/resttemplate/fluent/common/response/receive/QueryParametersSetting.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.receive; 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor.Executable; 4 | 5 | /** 6 | * Interface that provides methods to set query parameters on HTTP requests 7 | * 8 | * @param < T > - interface to return via {@link Executable} when you have finished setting query parameters 9 | */ 10 | public interface QueryParametersSetting extends Executable { 11 | QueryParametersSetting parameter(String name, Object value); 12 | } 13 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | com.ofg.infrastructure.tracing.TracingConfiguration 3 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/main/resources/static/collaborators/view.html: -------------------------------------------------------------------------------- 1 | Collaborators

-------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/base/BaseConfiguration.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.base 2 | 3 | import com.ofg.infrastructure.tracing.EnableTracing 4 | import groovy.transform.CompileStatic 5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration 6 | import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration 7 | import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration 8 | import org.springframework.cloud.sleuth.zipkin2.ZipkinAutoConfiguration 9 | import org.springframework.context.annotation.Bean 10 | import org.springframework.context.annotation.Configuration 11 | import org.springframework.context.annotation.EnableAspectJAutoProxy 12 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer 13 | 14 | @CompileStatic 15 | @EnableAspectJAutoProxy(proxyTargetClass = true) 16 | @Configuration 17 | @EnableTracing 18 | @EnableAutoConfiguration(exclude = [LoadBalancerAutoConfiguration, ZipkinAutoConfiguration, JmxAutoConfiguration]) 19 | class BaseConfiguration { 20 | 21 | @Bean 22 | static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { 23 | return new PropertySourcesPlaceholderConfigurer() 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/base/ConfigurationWithoutServiceDiscovery.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.base 2 | 3 | import com.ofg.infrastructure.web.correlationid.EnableCorrelationId 4 | import com.ofg.infrastructure.web.view.ViewConfiguration 5 | import groovy.transform.TypeChecked 6 | import org.springframework.context.annotation.Configuration 7 | import org.springframework.context.annotation.Import 8 | 9 | @TypeChecked 10 | @Configuration 11 | @EnableCorrelationId 12 | @Import([ViewConfiguration]) 13 | class ConfigurationWithoutServiceDiscovery { 14 | } 15 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/base/MicroserviceMvcWiremockSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.base 2 | 3 | import com.ofg.infrastructure.web.correlationid.HeadersSettingFilter 4 | import org.springframework.beans.factory.annotation.Autowired 5 | import org.springframework.cloud.sleuth.instrument.web.TraceFilter 6 | import org.springframework.test.context.ContextConfiguration 7 | import org.springframework.test.web.servlet.setup.ConfigurableMockMvcBuilder 8 | 9 | @ContextConfiguration(classes = [ServiceDiscoveryStubbingApplicationConfiguration]) 10 | abstract class MicroserviceMvcWiremockSpec extends MvcWiremockIntegrationSpec { 11 | 12 | @Autowired TraceFilter traceFilter 13 | 14 | @Override 15 | protected void configureMockMvcBuilder(ConfigurableMockMvcBuilder mockMvcBuilder) { 16 | super.configureMockMvcBuilder(mockMvcBuilder) 17 | mockMvcBuilder.addFilters(new HeadersSettingFilter(), traceFilter) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/base/MvcCorrelationIdSettingIntegrationSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.base 2 | 3 | import com.ofg.infrastructure.web.correlationid.HeadersSettingFilter 4 | import org.springframework.beans.factory.annotation.Autowired 5 | import org.springframework.cloud.sleuth.instrument.web.TraceFilter 6 | import org.springframework.cloud.sleuth.trace.SpanContextHolder 7 | import org.springframework.test.web.servlet.setup.ConfigurableMockMvcBuilder 8 | 9 | class MvcCorrelationIdSettingIntegrationSpec extends MvcIntegrationSpec { 10 | 11 | @Autowired protected TraceFilter filter 12 | 13 | @Override 14 | protected void configureMockMvcBuilder(ConfigurableMockMvcBuilder mockMvcBuilder) { 15 | super.configureMockMvcBuilder(mockMvcBuilder) 16 | mockMvcBuilder.addFilters(new HeadersSettingFilter(), filter) 17 | } 18 | 19 | def setup() { 20 | SpanContextHolder.removeCurrentSpan() 21 | } 22 | 23 | def cleanup() { 24 | SpanContextHolder.removeCurrentSpan() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/base/ServiceDiscoveryStubbingApplicationConfiguration.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.base 2 | 3 | import com.ofg.infrastructure.discovery.ServiceDiscoveryConfiguration 4 | import com.ofg.infrastructure.web.config.WebInfrastructureConfiguration 5 | import groovy.transform.TypeChecked 6 | import org.springframework.context.annotation.Configuration 7 | import org.springframework.context.annotation.Import 8 | 9 | @TypeChecked 10 | @Configuration 11 | @Import([ServiceDiscoveryConfiguration, WebInfrastructureConfiguration]) 12 | class ServiceDiscoveryStubbingApplicationConfiguration {} 13 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/hystrix/CircuitBreakers.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.hystrix 2 | 3 | import com.netflix.hystrix.HystrixCommand 4 | import com.netflix.hystrix.HystrixCommandProperties 5 | import groovy.transform.CompileStatic 6 | 7 | import static com.netflix.hystrix.HystrixCommand.Setter.withGroupKey 8 | import static com.netflix.hystrix.HystrixCommandGroupKey.Factory.asKey 9 | 10 | @CompileStatic 11 | class CircuitBreakers { 12 | 13 | static HystrixCommand.Setter anyWithTimeout(int timeoutInMillis) { 14 | //below workaround comes from https://jira.codehaus.org/browse/GROOVY-6286 15 | HystrixCommandProperties.Setter commandPropertiesSetter = 16 | (HystrixCommandProperties.Setter)HystrixCommandProperties.invokeMethod("Setter", null) 17 | return any().andCommandPropertiesDefaults(commandPropertiesSetter.withExecutionTimeoutInMilliseconds(timeoutInMillis)) 18 | } 19 | 20 | static HystrixCommand.Setter any() { 21 | return withGroupKey(asKey("")) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/metrics/config/GraphiteServiceConfig.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.metrics.config 2 | 3 | import com.ofg.infrastructure.discovery.ServiceConfigurationResolver 4 | import org.springframework.context.annotation.Bean 5 | import org.springframework.context.annotation.Configuration 6 | 7 | @Configuration 8 | class GraphiteServiceConfig { 9 | 10 | @Bean ServiceConfigurationResolver serviceConfigurationResolver() { 11 | return new ServiceConfigurationResolver(""" 12 | { 13 | "realm": { 14 | "this": "io/fourfinanceit/some-super-name" 15 | } 16 | } 17 | """) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/metrics/publishing/EnvironmentAwareMetricsBasePathSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.metrics.publishing 2 | 3 | import spock.lang.Specification 4 | 5 | class EnvironmentAwareMetricsBasePathSpec extends Specification { 6 | private static final ROOT = 'apps' 7 | private static final ENV = 'test' 8 | private static final COUNTRY = 'pl' 9 | private static final SERVICE = 'bluecash-adapter' 10 | 11 | def 'should construct metrics base path'() { 12 | given: 13 | EnvironmentAwareMetricsBasePath basePath = new EnvironmentAwareMetricsBasePath(ROOT, ENV, COUNTRY, SERVICE, 'node1') 14 | expect: 15 | basePath.path == "$ROOT.$ENV.$COUNTRY.${SERVICE}.node1" 16 | } 17 | 18 | def 'should replace dots in node name'() { 19 | given: 20 | EnvironmentAwareMetricsBasePath basePath = new EnvironmentAwareMetricsBasePath(ROOT, ENV, COUNTRY, SERVICE, nodeName) 21 | expect: 22 | basePath.path == "$ROOT.$ENV.$COUNTRY.${SERVICE}.$sanitizedNodeName" 23 | where: 24 | nodeName | sanitizedNodeName 25 | 'apl-001' | 'apl-001' 26 | 'apl-001.ofg.com' | 'apl-001_ofg_com' 27 | '192.168.1.5' | '192_168_1_5' 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/logging/RequestDataProviderTest.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging 2 | 3 | import spock.lang.Specification 4 | 5 | import static com.ofg.infrastructure.web.logging.HttpDataFactory.createHttpData 6 | import static feign.Response.create 7 | import static java.nio.charset.Charset.defaultCharset 8 | import static java.util.concurrent.TimeUnit.MILLISECONDS 9 | import static org.awaitility.Awaitility.await 10 | 11 | class RequestDataProviderTest extends Specification { 12 | 13 | private final static int TIME_TO_LIVE_MILLIS = 500; 14 | 15 | def 'Should delete httpData after specified time to live'() { 16 | given: 17 | RequestDataProvider provider = new RequestDataProvider(TIME_TO_LIVE_MILLIS); 18 | when: 19 | provider.store("1", httpData()); 20 | then: 21 | provider.retrieve("1") != null 22 | await().atMost(TIME_TO_LIVE_MILLIS + 500, MILLISECONDS).untilAsserted { 23 | assert provider.retrieve("1") == null 24 | } 25 | } 26 | 27 | private static HttpData httpData() { 28 | createHttpData(create(200, '', [:], 'content', defaultCharset())) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/logging/obfuscation/JsonPayloadObfuscatorSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging.obfuscation 2 | 3 | import spock.lang.Specification 4 | import spock.lang.Unroll 5 | 6 | class JsonPayloadObfuscatorSpec extends Specification { 7 | 8 | @Unroll 9 | def 'Should return input content when logic throws exception for : [#content]'() { 10 | given: 11 | ObfuscationFieldStrategy obfuscationFieldStrategy = Mock(ObfuscationFieldStrategy) 12 | JsonPayloadObfuscator obfuscator = new JsonPayloadObfuscator(obfuscationFieldStrategy) 13 | when: 14 | String result = obfuscator.process(content, ['filed']) 15 | then: 16 | result == content 17 | where: 18 | content << ['[[{]} broken content', '', ' ', null] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/logging/obfuscation/XmlPayloadObfuscatorSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging.obfuscation 2 | 3 | import spock.lang.Specification 4 | import spock.lang.Unroll 5 | 6 | class XmlPayloadObfuscatorSpec extends Specification { 7 | 8 | @Unroll 9 | def 'Should return input content when logic throws exception for : [#content]'() { 10 | given: 11 | ObfuscationFieldStrategy obfuscationFieldStrategy = Mock(ObfuscationFieldStrategy) 12 | XmlPayloadObfuscator obfuscator = new XmlPayloadObfuscator(obfuscationFieldStrategy) 13 | when: 14 | String result = obfuscator.process(content, Collections.emptyList()) 15 | then: 16 | result == content 17 | where: 18 | content << ['no xml content', '', ' ', null] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/logging/wrapper/HttpServletRequestLoggingWrapperSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging.wrapper 2 | 3 | import spock.lang.Specification 4 | 5 | import javax.servlet.ServletInputStream 6 | import javax.servlet.http.HttpServletRequest 7 | 8 | class HttpServletRequestLoggingWrapperSpec extends Specification { 9 | 10 | def 'Should return IllegalStateException when request input stream access ends with IOException'() { 11 | given: 12 | HttpServletRequest request = Mock(HttpServletRequest) 13 | request.getInputStream() >> {throw new IOException('any error')} 14 | when: 15 | new HttpServletRequestLoggingWrapper(request) 16 | then: 17 | thrown(IllegalStateException) 18 | } 19 | 20 | def 'Should return BufferedReader after wrapper initialization and reader call'() { 21 | given: 22 | HttpServletRequest request = Mock(HttpServletRequest) 23 | request.getInputStream() >> Mock(ServletInputStream) 24 | HttpServletRequestLoggingWrapper wrapper = new HttpServletRequestLoggingWrapper(request) 25 | expect: 26 | wrapper.getReader() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/logging/wrapper/HttpServletResponseLoggingWrapperSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.logging.wrapper 2 | 3 | import spock.lang.Specification 4 | 5 | import javax.servlet.http.HttpServletResponse 6 | 7 | class HttpServletResponseLoggingWrapperSpec extends Specification { 8 | 9 | def 'Should return IllegalStateException when response output stream access ends with IOException'() { 10 | given: 11 | HttpServletResponse response = Mock(HttpServletResponse) 12 | response.getOutputStream() >> {throw new IOException('any error')} 13 | when: 14 | new HttpServletResponseLoggingWrapper(response) 15 | then: 16 | thrown(IllegalStateException) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/resttemplate/custom/HttpStatusVerifierSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.custom 2 | 3 | import org.springframework.http.HttpStatus 4 | import spock.lang.Specification 5 | import spock.lang.Unroll 6 | 7 | class HttpStatusVerifierSpec extends Specification { 8 | 9 | def 'should verify that HTTP status [#status] is error [#error]'() { 10 | expect: 11 | error == HttpStatusVerifier.isError(status) 12 | where: 13 | status || error 14 | HttpStatus.PROCESSING || false 15 | HttpStatus.OK || false 16 | HttpStatus.TEMPORARY_REDIRECT || false 17 | HttpStatus.INTERNAL_SERVER_ERROR || true 18 | HttpStatus.BAD_REQUEST || true 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/resttemplate/custom/InputStreamPrinterSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.custom 2 | 3 | import spock.lang.Specification 4 | import spock.lang.Unroll 5 | 6 | class InputStreamPrinterSpec extends Specification { 7 | 8 | def 'should abbreviate "#source" to "#target" with max chars #maxChars'() { 9 | given: 10 | InputStream input = new ByteArrayInputStream(source.bytes) 11 | when: 12 | String abbreviated = InputStreamPrinter.abbreviate(input, maxChars) 13 | then: 14 | abbreviated == target 15 | where: 16 | source | maxChars || target 17 | '' | 0 || '' 18 | '' | 10 || '' 19 | 'abc' | 10 || 'abc' 20 | 'abcd' | 4 || 'abcd' 21 | 'abcde' | 4 || 'a...' 22 | 'abcdefghi' | 8 || 'abcde...' 23 | 'abcdefghi' | 10 || 'abcdefghi' 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/resttemplate/fluent/ComponentWithTwoRestOperationsImplementations.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent 2 | 3 | import org.springframework.web.client.RestOperations 4 | 5 | class ComponentWithTwoRestOperationsImplementations { 6 | 7 | private ServiceRestClient serviceRestClient 8 | private RestOperations restOperations 9 | 10 | ComponentWithTwoRestOperationsImplementations(ServiceRestClient serviceRestClient, 11 | RestOperations restOperations) { 12 | this.serviceRestClient = serviceRestClient 13 | this.restOperations = restOperations 14 | } 15 | 16 | void hasDependenciesInjectedCorrectly() { 17 | nonNullDependencies() 18 | nonMicroInfraSpringRestOperationsWasInjected() 19 | } 20 | 21 | private void nonNullDependencies() { 22 | assert serviceRestClient != null 23 | assert restOperations != null 24 | } 25 | 26 | private void nonMicroInfraSpringRestOperationsWasInjected() { 27 | assert restOperations instanceof TestRestTemplate 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/resttemplate/fluent/HTTPAuthorizationUtilsSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent 2 | 3 | import spock.lang.Specification 4 | import spock.lang.Unroll 5 | 6 | import static com.ofg.infrastructure.web.resttemplate.fluent.HTTPAuthorizationUtils.encodeCredentials 7 | 8 | class HTTPAuthorizationUtilsSpec extends Specification { 9 | 10 | def "encode basic authentication #username and #password credentials into #authorizationValue"() { 11 | when: 12 | def encodedResult = encodeCredentials(username, password) 13 | then: 14 | encodedResult == authorizationValue 15 | where: 16 | username | password || authorizationValue 17 | 'Aladdin' | 'open sesame' || 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==' 18 | 'Denis' | "Denis123" || 'RGVuaXM6RGVuaXMxMjM=' 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/resttemplate/fluent/TestRestTemplate.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent 2 | 3 | import org.springframework.web.client.RestTemplate 4 | 5 | class TestRestTemplate extends RestTemplate { 6 | } 7 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/HttpMethodSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common 2 | 3 | import com.ofg.infrastructure.web.resttemplate.fluent.FakeTrace 4 | import com.ofg.infrastructure.web.resttemplate.fluent.HttpMethodBuilder 5 | import com.ofg.infrastructure.web.resttemplate.fluent.TracingInfo 6 | import org.springframework.cloud.sleuth.TraceKeys 7 | import org.springframework.web.client.RestOperations 8 | import spock.lang.Specification 9 | 10 | class HttpMethodSpec extends Specification { 11 | 12 | protected static final String EVALUATED_SERVICE_URL = 'https://ofg.com.omg:9090' 13 | protected static final Closure SERVICE_URL = { EVALUATED_SERVICE_URL } 14 | protected static final String URL_TEMPLATE = '/api/objects/{objectId}' 15 | protected static final String FULL_URL = EVALUATED_SERVICE_URL + URL_TEMPLATE 16 | protected static final String PATH = 'api/objects/42' 17 | protected static final String PATH_WITH_SLASH = "/$PATH" 18 | 19 | protected static final String FULL_SERVICE_URL = "$EVALUATED_SERVICE_URL/$PATH" 20 | protected static final Long OBJECT_ID = 42L; 21 | 22 | RestOperations restOperations = Mock() 23 | HttpMethodBuilder httpMethodBuilder 24 | TracingInfo tracingInfo = new TracingInfo(new FakeTrace(), new TraceKeys()) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/resttemplate/fluent/common/response/executor/HttpEntityUtilsSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.resttemplate.fluent.common.response.executor 2 | 3 | import org.springframework.http.HttpEntity 4 | import org.springframework.http.HttpHeaders 5 | import spock.lang.Specification 6 | 7 | class HttpEntityUtilsSpec extends Specification { 8 | 9 | public static final int UNKOWN_HEADER_VALUE = -1 10 | 11 | def 'should create HttpEntity from a filled argument map'() { 12 | given: 13 | long expectedExpires = 1000 14 | String expectedBody = '''{"sample":"json"}''' 15 | Map args = [headers: new HttpHeaders(expires: expectedExpires), request: expectedBody] 16 | when: 17 | HttpEntity httpEntity = RestExecutor.getHttpEntityFrom(args) 18 | then: 19 | expectedExpires == httpEntity.headers.getExpires() 20 | expectedBody == httpEntity.body 21 | } 22 | 23 | def 'should create HttpEntity from an empty argument map'() { 24 | given: 25 | Map args = [:] 26 | when: 27 | HttpEntity httpEntity = RestExecutor.getHttpEntityFrom(args) 28 | then: 29 | httpEntity.headers.getExpires() == UNKOWN_HEADER_VALUE 30 | !httpEntity.body 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/view/DisablingJsonGeneratorFeaturesSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.view 2 | 3 | import com.fasterxml.jackson.core.JsonGenerator 4 | import spock.lang.Unroll 5 | 6 | import static com.ofg.infrastructure.web.view.JacksonFeaturesTestConstants.JACKSON_GENERATOR_FEATURES_AS_LIST 7 | 8 | class DisablingJsonGeneratorFeaturesSpec extends JsonJacksonFeaturesSpec { 9 | 10 | def setupSpec() { 11 | System.setProperty("json.jackson.generator.off", JACKSON_GENERATOR_FEATURES_AS_LIST.join(',')) 12 | } 13 | 14 | def cleanupSpec() { 15 | System.properties.remove("json.jackson.generator.off") 16 | } 17 | 18 | def "should enable JsonGenerator's feature #generatorFeature"() { 19 | given: 20 | def converter = getFirstConfiguredJacksonMessageConverter() 21 | def feature = JsonGenerator.Feature.valueOf(generatorFeature) 22 | expect: 23 | !converter.objectMapper.isEnabled(feature) 24 | where: 25 | generatorFeature << JACKSON_GENERATOR_FEATURES_AS_LIST 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/view/DisablingJsonParserFeaturesSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.view 2 | 3 | import com.fasterxml.jackson.core.JsonParser 4 | import spock.lang.Unroll 5 | 6 | import static com.ofg.infrastructure.web.view.JacksonFeaturesTestConstants.JACKSON_PARSER_FEATURES_AS_LIST 7 | 8 | class DisablingJsonParserFeaturesSpec extends JsonJacksonFeaturesSpec { 9 | 10 | def setupSpec() { 11 | System.setProperty("json.jackson.parser.off", JACKSON_PARSER_FEATURES_AS_LIST.join(',')) 12 | } 13 | 14 | def cleanupSpec() { 15 | System.properties.remove("json.jackson.parser.off") 16 | } 17 | 18 | def "should enable JsonParser's feature #parserFeature"() { 19 | given: 20 | def converter = getFirstConfiguredJacksonMessageConverter() 21 | def feature = JsonParser.Feature.valueOf(parserFeature) 22 | expect: 23 | !converter.objectMapper.isEnabled(feature) 24 | where: 25 | parserFeature << JACKSON_PARSER_FEATURES_AS_LIST 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/view/EnablingJsonGeneratorFeaturesSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.view 2 | 3 | import com.fasterxml.jackson.core.JsonGenerator 4 | import spock.lang.Unroll 5 | 6 | import static com.ofg.infrastructure.web.view.JacksonFeaturesTestConstants.JACKSON_GENERATOR_FEATURES_AS_LIST 7 | 8 | class EnablingJsonGeneratorFeaturesSpec extends JsonJacksonFeaturesSpec { 9 | 10 | def setupSpec() { 11 | System.setProperty("json.jackson.generator.on", JACKSON_GENERATOR_FEATURES_AS_LIST.join(',')) 12 | } 13 | 14 | def cleanupSpec() { 15 | System.properties.remove("json.jackson.generator.on") 16 | } 17 | 18 | def "should enable JsonGenerator's feature #generatorFeature"() { 19 | given: 20 | def converter = getFirstConfiguredJacksonMessageConverter() 21 | def feature = JsonGenerator.Feature.valueOf(generatorFeature) 22 | expect: 23 | converter.objectMapper.isEnabled(feature) 24 | where: 25 | generatorFeature << JACKSON_GENERATOR_FEATURES_AS_LIST 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/groovy/com/ofg/infrastructure/web/view/EnablingJsonParserFeaturesSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.web.view 2 | 3 | import com.fasterxml.jackson.core.JsonParser 4 | import spock.lang.Unroll 5 | 6 | import static com.ofg.infrastructure.web.view.JacksonFeaturesTestConstants.JACKSON_PARSER_FEATURES_AS_LIST 7 | 8 | 9 | class EnablingJsonParserFeaturesSpec extends JsonJacksonFeaturesSpec { 10 | 11 | def setupSpec() { 12 | System.setProperty("json.jackson.parser.on", JACKSON_PARSER_FEATURES_AS_LIST.join(',')) 13 | } 14 | 15 | def cleanupSpec() { 16 | System.properties.remove("json.jackson.parser.on") 17 | } 18 | 19 | def "should enable JsonParser's feature #parserFeature"() { 20 | given: 21 | def converter = getFirstConfiguredJacksonMessageConverter() 22 | def feature = JsonParser.Feature.valueOf(parserFeature) 23 | expect: 24 | converter.objectMapper.isEnabled(feature) 25 | where: 26 | parserFeature << JACKSON_PARSER_FEATURES_AS_LIST 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/resources/application-aspect.properties: -------------------------------------------------------------------------------- 1 | wiremock.port=8031 2 | stubrunner.stubs.repository.root=http://dl.bintray.com/4finance/micro 3 | stubrunner.stubs.group=com.ofg 4 | stubrunner.stubs.module=stub-runner-examples -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/resources/application-stub.properties: -------------------------------------------------------------------------------- 1 | stubrunner.stubs.repository.root=http://dl.bintray.com/4finance/micro 2 | stubrunner.stubs.group=com.ofg 3 | stubrunner.stubs.module=stub-runner-examples -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/resources/graphitePublishingDisabled.properties: -------------------------------------------------------------------------------- 1 | graphite.publishing.enabled=false -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/resources/graphitePublishingEnabled.properties: -------------------------------------------------------------------------------- 1 | graphite.publishing.enabled=on -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/resources/graphiteWithDefaultProps.properties: -------------------------------------------------------------------------------- 1 | metrics.path.country=country-not-from-json 2 | metrics.path.app=imaginary-app -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/resources/logback-test.groovy: -------------------------------------------------------------------------------- 1 | import ch.qos.logback.classic.encoder.PatternLayoutEncoder 2 | import ch.qos.logback.core.ConsoleAppender 3 | import org.springframework.cloud.sleuth.Span 4 | 5 | import static ch.qos.logback.classic.Level.DEBUG 6 | import static ch.qos.logback.classic.Level.INFO 7 | import static ch.qos.logback.classic.Level.WARN 8 | 9 | appender("CONSOLE", ConsoleAppender) { 10 | encoder(PatternLayoutEncoder) { 11 | pattern = "%d{HH:mm:ss.SSSZ} | %-5level | %X{${Span.TRACE_ID_NAME}} | %thread | %logger{1} | %m%n" 12 | } 13 | } 14 | 15 | //TODO: Fix console pollution during tests (it should be only logged to a test log file, but also available in Gradle test reports) 16 | root(WARN, ["CONSOLE"]) 17 | 18 | logger("com", INFO) 19 | logger("org", INFO) 20 | logger("com.ofg.infrastructure.web.resttemplate.custom.LoggingResponseExtractorWrapper", DEBUG) 21 | logger("com.ofg.infrastructure.web.logging.RequestResponseLogger", DEBUG) -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/resources/microservice.json: -------------------------------------------------------------------------------- 1 | { 2 | "pl": { 3 | "this": "foo/bar/registration", 4 | "dependencies": { 5 | "users": { 6 | "path": "foo/bar/users", 7 | "stubs": "foo.bar:users:stubs" 8 | }, 9 | "newsletter": { 10 | "path": "foo/bar/comms/newsletter" 11 | }, 12 | "confirmation": { 13 | "path": "foo/bar/security/confirmation" 14 | }, 15 | "foo-bar": { 16 | "path": "com/ofg/foo/bar" 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/resources/notPrettyPrinted.json: -------------------------------------------------------------------------------- 1 | {"sampleField":"sampleValue"} -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/resources/prettyPrinted.json: -------------------------------------------------------------------------------- 1 | { 2 | "sampleField" : "sampleValue" 3 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/resources/requestLogging/message_req.json: -------------------------------------------------------------------------------- 1 | { 2 | "affiliates": [], 3 | "clientGroup": null, 4 | "clientNumber": "999995", 5 | "companyBankAccount": "ES1100491893042710390399", 6 | "creditLimits": [ 7 | { 8 | "activeFrom": "2009-01-01", 9 | "limit": 300.0 10 | } 11 | ], 12 | "discountPercent": 0.0, 13 | "email": "antonio@mail.com", 14 | "grantedDiscounts": [], 15 | "id": 6, 16 | "identificationNumber": "38367554178", 17 | "landlinePhone": "982145983", 18 | "mobilePhone": "682145983", 19 | "personalId": "65464654F", 20 | "status": "IDENTIFIED", 21 | "surplusAmount": 0.0 , 22 | "requiredAdditionalDocuments" : [{"type":"PERSONAL_INVOICE", "attachmentFileName":"file.txt"}, 23 | {"type":"CERTIFICATE_OF_EMPLOYMENT", "attachmentFileName":"file.txt"}] 24 | } -------------------------------------------------------------------------------- /micro-infra-spring-base/src/test/resources/requestLogging/message_res.json: -------------------------------------------------------------------------------- 1 | { 2 | "affiliates": [], 3 | "clientGroup": null, 4 | "clientNumber": "999995", 5 | "companyBankAccount": "ES1100491893042710390399", 6 | "creditLimits": [ 7 | { 8 | "activeFrom": "2009-01-01", 9 | "limit": 300.0 10 | } 11 | ], 12 | "discountPercent": 0.0, 13 | "email": "antonio@mail.com", 14 | "grantedDiscounts": [], 15 | "id": 6, 16 | "identificationNumber": "38367554178", 17 | "landlinePhone": "982145983", 18 | "mobilePhone": "682145983", 19 | "personalId": "65464654F", 20 | "status": "IDENTIFIED", 21 | "surplusAmount": 0.0 , 22 | "requiredAdditionalDocuments" : [{"type":"PERSONAL_INVOICE", "attachmentFileName":"file.txt"}, 23 | {"type":"CERTIFICATE_OF_EMPLOYMENT", "attachmentFileName":"file.txt"}] 24 | } -------------------------------------------------------------------------------- /micro-infra-spring-boot-starter/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'Spring Boot Micro Infra Spring Starter' 2 | 3 | dependencies { 4 | compile project(':micro-infra-spring') 5 | compile project(':micro-infra-spring-config') 6 | } 7 | 8 | -------------------------------------------------------------------------------- /micro-infra-spring-boot-starter/src/main/java/com.ofg.infrastructure.autoconfigure/MicroserviceAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.autoconfigure; 2 | 3 | import com.ofg.config.NotSpringCloudProfile; 4 | import com.ofg.infrastructure.config.EnableMicroservice; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration 10 | * Auto-configuration} for Microservices. Equivalent to enabling 11 | * {@link com.ofg.infrastructure.autoconfigure.MicroserviceAutoConfiguration} in your configuration. 12 | *

13 | * The configuration will not be activated if {@literal com.ofg.infrastructure.microservice.auto=false}. 14 | * 15 | * @see com.ofg.infrastructure.config.EnableMicroservice 16 | */ 17 | @Configuration 18 | @ConditionalOnExpression("${com.ofg.infra.microservice.auto:true}") 19 | @EnableMicroservice 20 | @NotSpringCloudProfile 21 | public class MicroserviceAutoConfiguration { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /micro-infra-spring-boot-starter/src/main/java/com.ofg.infrastructure.autoconfigure/MicroserviceCircuitBreakingServletAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.autoconfigure; 2 | 3 | import com.ofg.infrastructure.hystrix.EnableHystrixServlet; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | /** 7 | * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration 8 | * Auto-configuration} for Microservices. Equivalent to enabling 9 | * {@link com.ofg.infrastructure.hystrix.HystrixServletConfiguration} in your configuration. 10 | *

11 | * Check {@link com.ofg.infrastructure.hystrix.IsHystrixServletEnabled} to see what conditions 12 | * need to be satisfied to register the servlet. 13 | * 14 | * @see EnableHystrixServlet 15 | * @see com.ofg.infrastructure.hystrix.IsHystrixServletEnabled 16 | */ 17 | @Configuration 18 | @EnableHystrixServlet 19 | public class MicroserviceCircuitBreakingServletAutoConfiguration { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /micro-infra-spring-boot-starter/src/main/java/com.ofg.infrastructure.autoconfigure/MicroserviceDocumentationAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.autoconfigure; 2 | 3 | import com.ofg.infrastructure.config.EnableMicroserviceDocumentation; 4 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration 10 | * Auto-configuration} for Swagger API Documentation. Equivalent to enabling 11 | * {@link com.ofg.infrastructure.config.EnableMicroserviceDocumentation} in your configuration. 12 | *

13 | * The configuration will not be activated if {@literal com.ofg.infra.microservice.documentation.auto=false}. 14 | * 15 | * @see com.ofg.infrastructure.config.EnableMicroserviceDocumentation 16 | */ 17 | @Configuration 18 | @ConditionalOnExpression("${com.ofg.infra.microservice.documentation.auto:true}") 19 | @AutoConfigureAfter(org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.class) 20 | @EnableMicroserviceDocumentation 21 | public class MicroserviceDocumentationAutoConfiguration { 22 | } 23 | -------------------------------------------------------------------------------- /micro-infra-spring-boot-starter/src/main/java/com.ofg.infrastructure.autoconfigure/SpringCloudMicroSetup.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.autoconfigure; 2 | 3 | import com.ofg.infrastructure.healthcheck.EnableHealthCheck; 4 | import com.ofg.infrastructure.metrics.config.EnableMetrics; 5 | import com.ofg.infrastructure.tracing.EnableTracing; 6 | import com.ofg.infrastructure.web.correlationid.EnableCorrelationId; 7 | import com.ofg.infrastructure.web.resttemplate.fluent.ServiceRestClientConfiguration; 8 | import com.ofg.infrastructure.web.view.ViewConfiguration; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.context.annotation.Import; 11 | 12 | @Configuration 13 | @EnableHealthCheck 14 | @EnableMetrics 15 | @EnableCorrelationId 16 | @EnableTracing 17 | @Import({ServiceRestClientConfiguration.class, ViewConfiguration.class}) 18 | public class SpringCloudMicroSetup { 19 | } 20 | -------------------------------------------------------------------------------- /micro-infra-spring-boot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.cloud.bootstrap.BootstrapConfiguration=\ 2 | com.ofg.infrastructure.discovery.SpringCloudZookeeperConfiguration,\ 3 | com.ofg.infrastructure.tracing.TracingPropertiesEnabler 4 | 5 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 6 | com.ofg.infrastructure.autoconfigure.MicroserviceAutoConfiguration,\ 7 | com.ofg.infrastructure.autoconfigure.MicroserviceDocumentationAutoConfiguration,\ 8 | com.ofg.infrastructure.autoconfigure.MicroserviceCircuitBreakingServletAutoConfiguration,\ 9 | com.ofg.infrastructure.autoconfigure.SpringCloudMicroSetup 10 | -------------------------------------------------------------------------------- /micro-infra-spring-config/README.md: -------------------------------------------------------------------------------- 1 | See: [Centralized configuration management](https://github.com/4finance/micro-infra-spring/wiki/Centralized-configuration-management) wiki. -------------------------------------------------------------------------------- /micro-infra-spring-config/src/main/java/com/ofg/infrastructure/property/EnableExternalProperties.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.property; 2 | 3 | import org.springframework.context.annotation.Import; 4 | 5 | @Import(ExternalPropertiesConfiguration.class) 6 | public @interface EnableExternalProperties { 7 | } 8 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/main/java/com/ofg/infrastructure/property/PollerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.property; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.cloud.context.scope.refresh.RefreshScope; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.context.annotation.Profile; 8 | import org.springframework.core.env.ConfigurableEnvironment; 9 | 10 | @Configuration 11 | @Profile("!test") 12 | public class PollerConfiguration { 13 | 14 | @Autowired 15 | private ConfigurableEnvironment environment; 16 | 17 | @Autowired 18 | private RefreshScope refreshScope; 19 | 20 | @Autowired FileSystemLocator fileSystemLocator; 21 | 22 | @Bean 23 | public FileSystemPoller fileSystemPoller() { 24 | return new FileSystemPoller(fileSystemLocator, environment, refreshScope); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/main/java/com/ofg/infrastructure/property/PropertiesFolderFinder.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.property; 2 | 3 | import static com.ofg.infrastructure.property.AppCoordinates.CONFIG_FOLDER; 4 | 5 | import java.io.File; 6 | 7 | class PropertiesFolderFinder { 8 | 9 | public static final File DEFAULT_CONFIG_DIR = new File(System.getProperty("user.home"), "config"); 10 | 11 | static File find() { 12 | final String configFolder = PropertyUtils.getProperty(CONFIG_FOLDER, null); 13 | return configFolder != null ? new File(configFolder) : DEFAULT_CONFIG_DIR; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/main/java/com/ofg/infrastructure/property/PropertyUtils.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.property; 2 | 3 | public class PropertyUtils { 4 | 5 | public static String getProperty(String name, String defValue) { 6 | final String valOrNull = System.getProperty(name); 7 | if (valOrNull == null) { 8 | final String envValueOrNull = System.getenv(name); 9 | return envValueOrNull != null ? envValueOrNull : defValue; 10 | } else { 11 | return valOrNull; 12 | } 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/main/java/com/ofg/infrastructure/property/SystemPropertiesOverridingPropertySourceLocator.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.property; 2 | 3 | import org.springframework.cloud.bootstrap.config.PropertySourceLocator; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.core.env.Environment; 6 | import org.springframework.core.env.MapPropertySource; 7 | import org.springframework.core.env.PropertySource; 8 | 9 | import java.util.Collections; 10 | 11 | @Configuration 12 | public class SystemPropertiesOverridingPropertySourceLocator implements PropertySourceLocator { 13 | @Override 14 | public PropertySource locate(Environment environment) { 15 | return new MapPropertySource("microInfraSpringCloudConfigSource", 16 | Collections.singletonMap("spring.cloud.config.overrideSystemProperties", "false")); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/main/java/com/ofg/infrastructure/property/decrypt/JceUnlimitedStrengthUtil.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.property.decrypt; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import javax.crypto.Cipher; 7 | import java.security.NoSuchAlgorithmException; 8 | 9 | import static java.lang.invoke.MethodHandles.lookup; 10 | 11 | public class JceUnlimitedStrengthUtil { 12 | 13 | private static final Logger log = LoggerFactory.getLogger(lookup().lookupClass()); 14 | 15 | public static void printWarningIfStrongEncryptionIsNotSupported() { 16 | if (!isStrongEncryptionSupported()) { 17 | log.warn("WARNING. It seems your JDK does not support strong encryption. " + 18 | "Install Java Cryptography Extension (JCE) Unlimited Strength for Oracle JDK or " + 19 | "use OpenJDK to have support for property decryption."); 20 | } 21 | } 22 | 23 | public static boolean isStrongEncryptionSupported() { 24 | try { 25 | return Cipher.getMaxAllowedKeyLength("AES") > 128; 26 | } catch (NoSuchAlgorithmException e) { 27 | log.warn("Error while checking if strong encryption is supported", e); 28 | return false; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | com.ofg.infrastructure.property.PollerConfiguration 3 | 4 | org.springframework.cloud.bootstrap.BootstrapConfiguration=\ 5 | com.ofg.infrastructure.property.ExternalPropertiesConfiguration,\ 6 | com.ofg.infrastructure.property.SystemPropertiesOverridingPropertySourceLocator -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/groovy/com/ofg/infrastructure/property/LoadingFromInvalidFileSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.property 2 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration 3 | import org.springframework.cloud.config.client.ConfigClientAutoConfiguration 4 | import org.springframework.context.annotation.ComponentScan 5 | import org.springframework.context.annotation.Configuration 6 | 7 | class LoadingFromInvalidFileSpec extends AbstractIntegrationSpec { 8 | 9 | def "should fail with meaningful error on invalid yaml file"() { 10 | given: 11 | System.setProperty('microservice.config.file', 'classpath:microservice-invalid.json') 12 | System.setProperty('spring.cloud.bootstrap.name', 'bootstrap-invalid') 13 | when: 14 | contextWithSources(AppWithInvalidConfig) 15 | then: 16 | def e = thrown(Exception) 17 | e.message.contains("invalid-app.yaml") 18 | } 19 | } 20 | 21 | @Configuration 22 | @EnableAutoConfiguration 23 | @ComponentScan(basePackageClasses = [ConfigClientAutoConfiguration.class]) 24 | class AppWithInvalidConfig { 25 | } 26 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/groovy/com/ofg/infrastructure/property/decrypt/BrokenJceInstallationWarningSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.property.decrypt 2 | 3 | import spock.lang.IgnoreIf 4 | import spock.lang.Specification 5 | 6 | import static com.ofg.infrastructure.property.decrypt.JceUnlimitedStrengthUtil.printWarningIfStrongEncryptionIsNotSupported 7 | import static com.ofg.infrastructure.property.decrypt.JceUnlimitedStrengthUtil.strongEncryptionSupported 8 | 9 | @IgnoreIf({ strongEncryptionSupported }) 10 | class BrokenJceInstallationWarningSpec extends Specification { 11 | 12 | def "WARNING. JCE US has to be installed for property values decryption"() { 13 | expect: 14 | printWarningIfStrongEncryptionIsNotSupported() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/groovy/com/ofg/infrastructure/property/decrypt/DecryptingPropertyTestApp.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.property.decrypt 2 | 3 | import org.springframework.cloud.config.client.ConfigClientAutoConfiguration 4 | import org.springframework.context.annotation.ComponentScan 5 | import org.springframework.context.annotation.Configuration 6 | 7 | @Configuration 8 | @ComponentScan(basePackageClasses = [ConfigClientAutoConfiguration.class]) 9 | class DecryptingPropertyTestApp { 10 | } 11 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/bootstrap-enc.yaml: -------------------------------------------------------------------------------- 1 | spring.application.name: com/ofg/micro-app-enc 2 | spring.cloud.zookeeper: 3 | discovery.root: pl -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/bootstrap-invalid.yaml: -------------------------------------------------------------------------------- 1 | spring.application.name: /io/invalid-app 2 | spring.cloud.zookeeper: 3 | discovery.root: iv -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/bootstrap-ok.yaml: -------------------------------------------------------------------------------- 1 | spring.application.name: com/ofg/micro-app 2 | spring.cloud.zookeeper: 3 | discovery.root: pl -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/decryptingPropertyTest.properties: -------------------------------------------------------------------------------- 1 | enc.application.prop={cipher}411fe0940df2296c4bc01be6477c030161961d1e0d231f1365ed33eab51d5f550aff707b249380c001b058aea074d07e -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/logback-test.groovy: -------------------------------------------------------------------------------- 1 | import ch.qos.logback.classic.encoder.PatternLayoutEncoder 2 | import ch.qos.logback.core.ConsoleAppender 3 | 4 | import static ch.qos.logback.classic.Level.DEBUG 5 | import static ch.qos.logback.classic.Level.INFO 6 | 7 | appender("CONSOLE", ConsoleAppender) { 8 | encoder(PatternLayoutEncoder) { 9 | pattern = "%d{HH:mm:ss.SSSZ} | %-5level | %X{X-B3-TraceId} | %thread | %logger{1} | %m%n" 10 | } 11 | } 12 | 13 | //TODO: Fix console pollution during tests (it should be only logged to a test log file, but also available in Gradle test reports) 14 | root(INFO, ["CONSOLE"]) 15 | 16 | logger("com.ofg", DEBUG) 17 | logger("org.springframework.cloud.config.client", DEBUG) 18 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/microservice-enc.json: -------------------------------------------------------------------------------- 1 | { 2 | "pl": { 3 | "this": "/com/ofg/micro-app-enc" 4 | } 5 | } -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/microservice-invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "iv": { 3 | "this": "/io/invalid-app" 4 | } 5 | } -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/microservice.json: -------------------------------------------------------------------------------- 1 | { 2 | "pl": { 3 | "this": "/com/ofg/micro-app" 4 | } 5 | } -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/common/com/ofg/micro-app.properties: -------------------------------------------------------------------------------- 1 | common.prop.key=common prop value 2 | global.default.prop.key=overridden common default prop value 3 | custom.common.key=custom common prop value -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/common/com/ofg/micro-app.yaml: -------------------------------------------------------------------------------- 1 | common: 2 | yaml: 3 | key: common yaml value 4 | global: 5 | default: 6 | yaml: 7 | key: overridden common default yaml value 8 | custom: 9 | common: 10 | key: custom common yaml value -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/common/com/ofg/pl/micro-app-pl.properties: -------------------------------------------------------------------------------- 1 | common.country.prop.key=common country prop value 2 | global.default.prop.key=overridden global country-specific prop value 3 | custom.common.country.key=custom common country prop value -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/common/com/ofg/pl/micro-app-pl.yaml: -------------------------------------------------------------------------------- 1 | common: 2 | country: 3 | yaml: 4 | key: common country yaml value 5 | global: 6 | default: 7 | yaml: 8 | key: overridden global country-specific yaml value 9 | custom: 10 | common: 11 | country: 12 | key: custom common country yaml value -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/common/global.properties: -------------------------------------------------------------------------------- 1 | global.prop.key=global prop value 2 | global.default.prop.key=common default prop value 3 | custom.global.key=custom global prop value 4 | 5 | logger.filename=logs/fake123Logger.log 6 | logger.log.pattern=fake123LoggerPattern| %m%n 7 | logger.scan.time=123 minutes 8 | logger.rolling.filename.pattern=logs/fake123Logger.%d{yyyy-MM-dd}.log.zip 9 | logger.rolling.history.max=123 -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/common/global.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | yaml: 3 | key: global yaml value 4 | default: 5 | yaml: 6 | key: global default yaml value 7 | url: http://example.com 8 | custom: 9 | global: 10 | key: custom global yaml value -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/prod/com/ofg/micro-app-enc.properties: -------------------------------------------------------------------------------- 1 | country.prop.secret={cipher}85f21553dcb4778ef25432df218dc672106e169c970db3c6f996567b9ff4ca3712f0d3b065aa5b44116a1ded0476c05e 2 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/prod/com/ofg/micro-app-enc.yaml: -------------------------------------------------------------------------------- 1 | country: 2 | yaml: 3 | secret: "{cipher}f29ed1c69fa39d4d33c72305a2bf49bf30f2841aa1e9da7e052e3338fe045abc30de68ae5047e708c2372714f0e4d6ce" 4 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/prod/com/ofg/micro-app.properties: -------------------------------------------------------------------------------- 1 | env.prop.key=env prop value 2 | global.default.prop.key=overridden env prop value 3 | custom.env.key=custom env prop value 4 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/prod/com/ofg/micro-app.yaml: -------------------------------------------------------------------------------- 1 | env: 2 | yaml: 3 | key: env yaml value 4 | global: 5 | default: 6 | yaml: 7 | key: overridden env yaml value 8 | custom: 9 | env: 10 | key: custom env yaml value -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/prod/com/ofg/pl/micro-app-pl.properties: -------------------------------------------------------------------------------- 1 | country.prop.key=country prop value 2 | global.default.prop.key=overridden country-specific prop value 3 | custom.country.key=custom country prop value -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/prod/com/ofg/pl/micro-app-pl.yaml: -------------------------------------------------------------------------------- 1 | country: 2 | yaml: 3 | key: country yaml value 4 | global: 5 | default: 6 | yaml: 7 | key: overridden country-specific yaml value 8 | custom: 9 | country: 10 | key: custom country yaml value -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/test-config-dir/prod/io/invalid-app.yaml: -------------------------------------------------------------------------------- 1 | keyForUnquotedCurlyBraces: {cipher}aKey 2 | -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/testConfigurationWithConfigurationProperties.properties: -------------------------------------------------------------------------------- 1 | enc.configurationProperties={cipher}7b11e6e32bf28eb1820553c042d9a7302065229c6aa0c159cacd5e47d4f45f15817313409fd2945e628e1c55094cddd45b56a60f60a1f16a1d1f8b7e3ed2b1e9 -------------------------------------------------------------------------------- /micro-infra-spring-config/src/test/resources/testConfigurationWithPropertySource.properties: -------------------------------------------------------------------------------- 1 | enc.propertySource.prop={cipher}85f21553dcb4778ef25432df218dc672106e169c970db3c6f996567b9ff4ca3712f0d3b065aa5b44116a1ded0476c05e -------------------------------------------------------------------------------- /micro-infra-spring-swagger/build.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | springfoxVersion = '2.8.0' 3 | } 4 | 5 | dependencies { 6 | compile "io.springfox:springfox-swagger-ui:${springfoxVersion}" 7 | compile "io.springfox:springfox-core:${springfoxVersion}" 8 | compile "io.springfox:springfox-spi:${springfoxVersion}" 9 | compile "io.springfox:springfox-schema:${springfoxVersion}" 10 | compile "io.springfox:springfox-spring-web:${springfoxVersion}" 11 | compile "io.springfox:springfox-swagger2:${springfoxVersion}" 12 | compile 'org.springframework.boot:spring-boot-starter-web' 13 | } 14 | -------------------------------------------------------------------------------- /micro-infra-spring-swagger/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/4finance/micro-infra-spring/2479deec28bad8c9b05cbae92219041c34a39261/micro-infra-spring-swagger/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /micro-infra-spring-test/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'Microservice testing utilities' 2 | 3 | dependencies { 4 | compile project(':micro-deps-root:micro-deps-spring-test-config') 5 | } 6 | -------------------------------------------------------------------------------- /micro-infra-spring/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'Default set-up for 4finance microservices' 2 | 3 | dependencies { 4 | compile project(':micro-infra-spring-base') 5 | compile project(':micro-infra-spring-swagger') 6 | } 7 | -------------------------------------------------------------------------------- /micro-infra-spring/src/main/java/com/ofg/infrastructure/config/EnableMicroserviceDocumentation.java: -------------------------------------------------------------------------------- 1 | package com.ofg.infrastructure.config; 2 | 3 | import com.ofg.infrastructure.web.swagger.SwaggerConfiguration; 4 | import org.springframework.context.annotation.Import; 5 | 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * Enables support for Swagger API Documentation. 13 | * 14 | * @see SwaggerConfiguration 15 | */ 16 | @Target(ElementType.TYPE) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Import(SwaggerConfiguration.class) 19 | public @interface EnableMicroserviceDocumentation { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':stub-runner:stub-runner' 2 | include ':stub-runner:stub-runner-spring' 3 | include 'micro-infra-spring-boot-starter' 4 | include 'micro-infra-spring-base' 5 | include 'micro-infra-spring-test' 6 | include 'micro-infra-camel' 7 | include 'micro-infra-spring-swagger' 8 | include 'micro-infra-spring' 9 | include 'micro-infra-spring-config' 10 | include ':micro-deps:micro-deps' 11 | include ':micro-deps:micro-deps-jax-rs-jersey' 12 | include ':micro-deps:micro-deps-spring-config' 13 | include ':micro-deps:micro-deps-spring-test-config' 14 | include ':activity-tracker-root' 15 | include ':activity-tracker-root:activity-tracker' 16 | include ':activity-tracker-root:activity-tracker-boot-starter' 17 | 18 | rootProject.name = 'micro-infra-spring-root' 19 | 20 | //to prevent StackOverflow in Sonar 21 | project(":micro-deps").name = "micro-deps-root" 22 | project(":stub-runner").name = "stub-runner-root" 23 | -------------------------------------------------------------------------------- /stub-runner/stub-runner-spring/README.md: -------------------------------------------------------------------------------- 1 | stub-runner-spring 2 | ======================= 3 | 4 | Sets up spring configuration of our implementation of Consumer Driven Contracts. For more information about that please 5 | check the [Stub Runner project](https://github.com/4finance/micro-infra-spring/wiki/Stub-runner) 6 | 7 | Check out [the wiki](https://github.com/4finance/micro-infra-spring/wiki/Stub-runner) to have a deeper insight into the project. -------------------------------------------------------------------------------- /stub-runner/stub-runner-spring/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'Spring configuration for stub-runner' 2 | 3 | dependencies { 4 | compile project(':micro-deps-root:micro-deps') 5 | compile project(':stub-runner-root:stub-runner') 6 | compile 'org.springframework.cloud:spring-cloud-starter-zookeeper-discovery' 7 | 8 | compile 'org.codehaus.groovy:groovy-all' 9 | compile 'org.springframework:spring-context' 10 | compile 'org.apache.ivy:ivy:2.4.0' 11 | 12 | testCompile 'org.spockframework:spock-core' 13 | testCompile 'info.solidsoft.spock:spock-global-unroll' 14 | testCompile 'cglib:cglib-nodep' 15 | testCompile 'org.objenesis:objenesis' 16 | } 17 | -------------------------------------------------------------------------------- /stub-runner/stub-runner-spring/src/main/groovy/com/ofg/stub/config/ServiceDiscoveryTestingServerConfiguration.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.config 2 | 3 | import com.google.common.base.Strings 4 | import com.ofg.stub.util.PortResolver 5 | import groovy.transform.CompileStatic 6 | import org.apache.curator.test.TestingServer 7 | import org.springframework.beans.factory.annotation.Value 8 | import org.springframework.context.annotation.Bean 9 | import org.springframework.context.annotation.Configuration 10 | 11 | @Configuration 12 | @CompileStatic 13 | class ServiceDiscoveryTestingServerConfiguration { 14 | 15 | /** 16 | * Provides test instance of Zookeeper. If {@code serviceResolverUrl} is {@code null} or an empty string a randomly selected, available port is used. 17 | * 18 | * @param serviceResolverUrl - host with port where your application will search for Zookeeper instance 19 | * 20 | * @throws IllegalArgumentException when port in provided URL is not parseable, i.e. it is not numeric value 21 | */ 22 | @Bean(destroyMethod = 'close') 23 | TestingServer testingServer(@Value('${service.resolver.url:}') String serviceResolverUrl) { 24 | String serviceUrl = Strings.nullToEmpty(serviceResolverUrl) 25 | return new TestingServer(PortResolver.tryGetPortFromUrl(serviceUrl).or(-1)) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /stub-runner/stub-runner-spring/src/main/groovy/com/ofg/stub/util/PortResolver.java: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.util; 2 | 3 | import com.google.common.base.Optional; 4 | import com.google.common.net.HostAndPort; 5 | import org.apache.commons.lang.StringUtils; 6 | 7 | import static com.google.common.base.Preconditions.checkNotNull; 8 | import static com.google.common.base.Strings.isNullOrEmpty; 9 | 10 | public class PortResolver { 11 | 12 | 13 | /** 14 | * Returns port number from service url 15 | * 16 | * @param url host and port url in format hostname:port 17 | * @return empty if no port present or port 18 | * @throws IllegalArgumentException when url don't have colon 19 | */ 20 | public static Optional tryGetPortFromUrl(String url) { 21 | checkNotNull(url); 22 | if (isNullOrEmpty(StringUtils.substringAfterLast(url, ":"))) { 23 | return Optional.absent(); 24 | } else { 25 | return Optional.of(HostAndPort.fromString(url).getPort()); 26 | } 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /stub-runner/stub-runner-spring/src/test/groovy/com/ofg/stub/util/PortResolverSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.util 2 | 3 | import com.google.common.base.Optional 4 | import spock.lang.Specification 5 | 6 | class PortResolverSpec extends Specification { 7 | 8 | def "returns NullPointerException when null"() { 9 | when: 10 | PortResolver.tryGetPortFromUrl(null) 11 | then: 12 | thrown(NullPointerException) 13 | } 14 | 15 | def "returns correct port"() { 16 | when: 17 | Optional random = PortResolver.tryGetPortFromUrl("localhost:2000") 18 | then: 19 | random.get() == 2000 20 | } 21 | 22 | def "return absent if no port present"() { 23 | when: 24 | Optional port = PortResolver.tryGetPortFromUrl("localhost:") 25 | then: 26 | !port.isPresent() 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/repository/mappings/com/ofg/another/mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/another" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "Another project", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/repository/mappings/com/ofg/foo/bar/foobar.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/foobar" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "foobar", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/repository/mappings/com/ofg/ping/ping.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/ping" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "pong", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/repository/mappings/pl/com/ofg/foo/bar/pl_foobar.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/pl/foobar" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "foobar Poland", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/repository/projects/fooBar.json: -------------------------------------------------------------------------------- 1 | { 2 | "pl": [ 3 | "com/ofg/foo/bar" 4 | ] 5 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/repository/projects/healthCheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "pl": [ 3 | "com/ofg/ping" 4 | ] 5 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/Arguments.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub 2 | 3 | import com.ofg.stub.mapping.ProjectMetadata 4 | import groovy.transform.CompileStatic 5 | import groovy.transform.ToString 6 | 7 | /** 8 | * Arguments passed to the {@link StubRunner} application 9 | * 10 | * @see StubRunner 11 | */ 12 | @CompileStatic 13 | @ToString(includeNames = true) 14 | class Arguments { 15 | final StubRunnerOptions stubRunnerOptions 16 | final String context 17 | final String repositoryPath 18 | final String serviceName 19 | final List projects 20 | 21 | Arguments(StubRunnerOptions stubRunnerOptions, String context, String repositoryPath, String serviceName, List projects = null) { 22 | this.stubRunnerOptions = stubRunnerOptions 23 | this.context = context 24 | this.repositoryPath = repositoryPath 25 | this.projects = projects 26 | this.serviceName = serviceName 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/BatchStubRunner.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub 2 | 3 | import com.google.common.base.Optional 4 | import groovy.transform.CompileStatic 5 | 6 | /** 7 | * Manages lifecycle of multiple {@link StubRunner} instances. 8 | * 9 | * @see StubRunner 10 | */ 11 | @CompileStatic 12 | class BatchStubRunner implements StubRunning { 13 | 14 | private final Iterable stubRunners 15 | 16 | BatchStubRunner(Iterable stubRunners) { 17 | this.stubRunners = stubRunners 18 | } 19 | 20 | @Override 21 | void runStubs() { 22 | stubRunners.each { 23 | it.runStubs() 24 | } 25 | } 26 | 27 | @Override 28 | Optional findStubUrlByRelativePath(String relativePath) { 29 | return stubRunners.findResult(Optional.absent()) { StubRunner stubRunner -> 30 | def optionalUrl = stubRunner.findStubUrlByRelativePath(relativePath) 31 | if(optionalUrl.present) { 32 | return optionalUrl 33 | } 34 | } as Optional 35 | } 36 | 37 | @Override 38 | void close() throws IOException { 39 | stubRunners.each { 40 | it.close() 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/Collaborators.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub 2 | 3 | import com.ofg.infrastructure.discovery.MicroserviceConfiguration 4 | import groovy.transform.CompileStatic 5 | import groovy.transform.Immutable 6 | import groovy.transform.ToString 7 | 8 | /** 9 | * Structure representing collaborators together with their base path 10 | */ 11 | @ToString 12 | @Immutable 13 | @CompileStatic 14 | class Collaborators { 15 | String basePath 16 | List collaboratorsPath 17 | Map stubsPaths 18 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/DescriptorToCollaborators.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub 2 | 3 | import com.ofg.infrastructure.discovery.ServiceConfigurationResolver 4 | import groovy.transform.CompileStatic 5 | 6 | @CompileStatic 7 | class DescriptorToCollaborators { 8 | 9 | static Collaborators fromDeprecatedMicroserviceDescriptor(ServiceConfigurationResolver serviceConfigurationResolver) { 10 | return new Collaborators(serviceConfigurationResolver.basePath, 11 | serviceConfigurationResolver.dependencies.collect { 12 | it.servicePath.path 13 | }, serviceConfigurationResolver.dependencies.collectEntries { 14 | [it.servicePath.path, it.stubs] 15 | }) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/StubDownloader.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub 2 | 3 | interface StubDownloader { 4 | 5 | File downloadAndUnpackStubJar(String stubsGroup, String stubsModule, String classifier) 6 | 7 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/StubRunning.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub 2 | 3 | import com.google.common.base.Optional 4 | 5 | interface StubRunning extends Closeable { 6 | void runStubs() 7 | Optional findStubUrlByRelativePath(String relativePath) 8 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/UnknownDependencyException.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub 2 | 3 | import groovy.transform.CompileStatic 4 | import groovy.transform.InheritConstructors 5 | 6 | @CompileStatic 7 | @InheritConstructors 8 | class UnknownDependencyException extends RuntimeException { 9 | 10 | UnknownDependencyException(String dependencyPath) { 11 | super("Unknown dependency with path '$dependencyPath'") 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/mapping/InvalidRepositoryLayout.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.mapping 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class InvalidRepositoryLayout extends RuntimeException { 7 | InvalidRepositoryLayout(String message) { 8 | super(message) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/mapping/MappingDescriptor.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.mapping 2 | 3 | import com.github.tomakehurst.wiremock.stubbing.StubMapping 4 | import groovy.transform.CompileStatic 5 | import groovy.transform.EqualsAndHashCode 6 | import groovy.transform.ToString 7 | 8 | import static com.ofg.stub.mapping.MappingDescriptor.MappingType.GLOBAL 9 | 10 | @CompileStatic 11 | @EqualsAndHashCode 12 | @ToString 13 | class MappingDescriptor { 14 | final File descriptor 15 | final MappingType mappingType 16 | 17 | MappingDescriptor(File mappingDescriptor) { 18 | this.descriptor = mappingDescriptor 19 | this.mappingType = GLOBAL 20 | } 21 | 22 | MappingDescriptor(File mappingDescriptor, MappingType mappingType) { 23 | this.descriptor = mappingDescriptor 24 | this.mappingType = mappingType 25 | } 26 | 27 | StubMapping getMapping() { 28 | return StubMapping.buildFrom(descriptor.getText('UTF-8')) 29 | } 30 | 31 | static enum MappingType { 32 | GLOBAL, REALM_SPECIFIC 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/mapping/NoContextProvidedException.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.mapping 2 | 3 | import groovy.transform.InheritConstructors 4 | 5 | @InheritConstructors 6 | class NoContextProvidedException extends RuntimeException { 7 | } 8 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/mapping/ProjectMetadata.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.mapping 2 | 3 | import groovy.transform.CompileStatic 4 | import groovy.transform.EqualsAndHashCode 5 | import groovy.transform.ToString 6 | 7 | @CompileStatic 8 | @ToString(includeNames = true) 9 | @EqualsAndHashCode 10 | class ProjectMetadata { 11 | final String projectName 12 | final String projectRelativePath 13 | final String context 14 | 15 | ProjectMetadata(String projectName, String projectRelativePath, String context) { 16 | this.projectName = projectName 17 | this.projectRelativePath = projectRelativePath 18 | this.context = context 19 | } 20 | 21 | String getPathWithContext() { 22 | return "$context/$projectRelativePath" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/mapping/ProjectMetadataRepository.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.mapping 2 | 3 | import groovy.transform.CompileStatic 4 | import groovy.transform.PackageScope 5 | 6 | @PackageScope 7 | @CompileStatic 8 | class ProjectMetadataRepository { 9 | @PackageScope final File path 10 | 11 | ProjectMetadataRepository(File repository) { 12 | if (!repository.isDirectory()) { 13 | throw new InvalidRepositoryLayout('missing project metadata repository') 14 | } 15 | path = repository 16 | } 17 | 18 | URI getMetadataLocation(String metadataFileName) { 19 | return new File(path, metadataFileName).toURI() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/groovy/com/ofg/stub/mapping/StubRepository.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.mapping 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class StubRepository { 7 | static final String DEFAULT_DESCRIPTORS_DIRECTORY = 'mappings' 8 | 9 | private final DescriptorRepository descriptorRepository 10 | 11 | StubRepository(File repositoryRoot) { 12 | File descriptorDirectory = new File(repositoryRoot, DEFAULT_DESCRIPTORS_DIRECTORY) 13 | if (!descriptorDirectory.exists()) { 14 | repositoryRoot.eachDirRecurse { 15 | if (it.name == DEFAULT_DESCRIPTORS_DIRECTORY) { 16 | descriptorDirectory = it 17 | } 18 | } 19 | } 20 | descriptorRepository = new DescriptorRepository(descriptorDirectory) 21 | } 22 | 23 | List getProjectDescriptors(ProjectMetadata project) { 24 | return descriptorRepository.getProjectDescriptors(project) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/main/resources/microInfraGrapeConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/groovy/com/ofg/stub/BatchStubRunnerSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub 2 | 3 | import com.google.common.base.Optional 4 | import spock.lang.Specification 5 | 6 | class BatchStubRunnerSpec extends Specification { 7 | 8 | static final String KNOWN_STUB_PATH = 'com/ofg/ping' 9 | static final String UNKNOWN_STUB_PATH = 'com/ofg/unknown' 10 | static final URL KNOWN_STUB_URL = new URL('http://localhost:8080') 11 | 12 | def 'should provide stub URL from enclosed stub runner'() { 13 | given: 14 | BatchStubRunner batchStubRunner = new BatchStubRunner(runners()) 15 | expect: 16 | batchStubRunner.findStubUrlByRelativePath(KNOWN_STUB_PATH).get() == KNOWN_STUB_URL 17 | } 18 | 19 | def 'should return empty optional for unknown stub path'() { 20 | given: 21 | BatchStubRunner batchStubRunner = new BatchStubRunner(runners()) 22 | expect: 23 | !batchStubRunner.findStubUrlByRelativePath(UNKNOWN_STUB_PATH).present 24 | } 25 | 26 | List runners() { 27 | StubRunner runner = Mock(StubRunner) 28 | runner.findStubUrlByRelativePath(KNOWN_STUB_PATH) >> Optional.of(KNOWN_STUB_URL) 29 | runner.findStubUrlByRelativePath(UNKNOWN_STUB_PATH) >> Optional.absent() 30 | return [runner] 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/groovy/com/ofg/stub/mapping/DescriptorRepositorySpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.mapping 2 | 3 | import org.junit.Rule 4 | import org.junit.rules.TemporaryFolder 5 | import spock.lang.Specification 6 | 7 | class DescriptorRepositorySpec extends Specification { 8 | 9 | @Rule public TemporaryFolder tempPath = new TemporaryFolder(); 10 | 11 | def 'should fail to initialize stub repository when descriptors directory is missing'() { 12 | given: 13 | File doesNotExists = new File(tempPath.newFolder(), 'doesNotExists') 14 | when: 15 | new DescriptorRepository(doesNotExists) 16 | then: 17 | thrown(InvalidRepositoryLayout) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/groovy/com/ofg/stub/mapping/MappingDescriptorSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.mapping 2 | 3 | import spock.lang.Specification 4 | 5 | import static com.github.tomakehurst.wiremock.http.RequestMethod.GET 6 | 7 | class MappingDescriptorSpec extends Specification { 8 | public static final File MAPPING_DESCRIPTOR = new File('src/test/resources/repository/mappings/com/ofg/ping/ping.json') 9 | 10 | def 'should describe stub mapping'() { 11 | given: 12 | MappingDescriptor mappingDescriptor = new MappingDescriptor(MAPPING_DESCRIPTOR) 13 | 14 | expect: 15 | with(mappingDescriptor.mapping) { 16 | request.method == GET 17 | request.url == '/ping' 18 | response.status == 200 19 | response.body == 'pong' 20 | response.headers.contentTypeHeader.mimeTypePart() == 'text/plain' 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/groovy/com/ofg/stub/mapping/ProjectMetadataRepositorySpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.mapping 2 | 3 | import org.junit.Rule 4 | import org.junit.rules.TemporaryFolder 5 | import spock.lang.Specification 6 | 7 | class ProjectMetadataRepositorySpec extends Specification { 8 | 9 | @Rule public TemporaryFolder tempPath = new TemporaryFolder(); 10 | 11 | def 'should fail to initialize repository when projects metadata directory is missing'() { 12 | given: 13 | File doesNotExists = new File(tempPath.newFolder(), 'doesNotExists') 14 | when: 15 | new ProjectMetadataRepository(doesNotExists) 16 | then: 17 | thrown(InvalidRepositoryLayout) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/groovy/com/ofg/stub/mapping/ProjectMetadataSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.mapping 2 | 3 | import spock.lang.Specification 4 | 5 | class ProjectMetadataSpec extends Specification { 6 | 7 | def 'should build full path with context'() { 8 | given: 9 | String projectName = 'ping' 10 | String projectPath = 'com/ofg/ping' 11 | String context = 'lv' 12 | ProjectMetadata projectMetadata = new ProjectMetadata(projectName, projectPath, context) 13 | expect: 14 | projectMetadata.pathWithContext == "$context/$projectPath" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/groovy/com/ofg/stub/util/ZipCategorySpec.groovy: -------------------------------------------------------------------------------- 1 | package com.ofg.stub.util 2 | 3 | import groovy.util.logging.Slf4j 4 | import spock.lang.Specification 5 | 6 | @Slf4j 7 | class ZipCategorySpec extends Specification { 8 | 9 | def 'should unzip a file to the specified location'() { 10 | given: 11 | File zipFile = new File(ZipCategorySpec.classLoader.getResource('file.zip').toURI()) 12 | File tempDir = File.createTempDir() 13 | tempDir.deleteOnExit() 14 | when: 15 | use(ZipCategory) { 16 | zipFile.unzipTo(tempDir) 17 | } 18 | then: 19 | tempDir.listFiles().find { 20 | it.name == 'file.txt' 21 | }?.text?.trim() == 'test' 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/bar/bar.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/bar" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "bar", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/bar/foobar.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/foobar" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "foobar", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/foo.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/foo" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "foo", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json: -------------------------------------------------------------------------------- 1 | { 2 | "pl": [ 3 | "com/ofg/bar" 4 | ] 5 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json: -------------------------------------------------------------------------------- 1 | { 2 | "pl": [ 3 | "com/ofg/foo/bar" 4 | ] 5 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/anotherRepository/projects/descriptor.json: -------------------------------------------------------------------------------- 1 | { 2 | "pl": [ 3 | "com/ofg/foo" 4 | ] 5 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/deepenMappingsRepository/deeper/located/mappings/com/ofg/bye/admin/admin.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/admin" 5 | }, 6 | "response": { 7 | "status": 401 8 | } 9 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/deepenMappingsRepository/deeper/located/mappings/com/ofg/bye/bye.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/bye" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "Goodbye world!", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/deepenMappingsRepository/deeper/located/mappings/com/ofg/ping/ping.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/ping" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "pong", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/deepenMappingsRepository/deeper/located/mappings/pl/com/ofg/bye/pl_bye.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/pl/bye" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "pl-bye", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/deepenMappingsRepository/deeper/located/mappings/pl/com/ofg/bye/pl_overridden_bye.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "request": { 4 | "method": "GET", 5 | "url": "/bye" 6 | }, 7 | "response": { 8 | "status": 200, 9 | "body": "overridden-bye", 10 | "headers": { 11 | "Content-Type": "text/plain" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/file.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/4finance/micro-infra-spring/2479deec28bad8c9b05cbae92219041c34a39261/stub-runner/stub-runner/src/test/resources/file.zip -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/microservice_example.json: -------------------------------------------------------------------------------- 1 | { 2 | "pl": { 3 | "this": "com/ofg/testService", 4 | "dependencies": { 5 | "ping": { 6 | "path": "com/ofg/ping", 7 | "stubs": "com.ofg:ping" 8 | }, 9 | "pong": { 10 | "path": "com/ofg/pong", 11 | "stubs": "com.ofg:pong" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/admin/admin.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/admin" 5 | }, 6 | "response": { 7 | "status": 401 8 | } 9 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/bye.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/bye" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "Goodbye world!", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/README.md: -------------------------------------------------------------------------------- 1 | ### Hello service stub -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/admin/admin.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/admin" 5 | }, 6 | "response": { 7 | "status": 401 8 | } 9 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/hello.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/hello" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "Hello world!", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/ping/ping.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/ping" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "pong", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/repository/mappings/lv/com/ofg/bye/lv_bye.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/lv/bye" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "Another goodbye world!", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_bye.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/pl/bye" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "pl-bye", 9 | "headers": { 10 | "Content-Type": "text/plain" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_overridden_bye.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "request": { 4 | "method": "GET", 5 | "url": "/bye" 6 | }, 7 | "response": { 8 | "status": 200, 9 | "body": "overridden-bye", 10 | "headers": { 11 | "Content-Type": "text/plain" 12 | } 13 | } 14 | } --------------------------------------------------------------------------------