Skip to content

Commit

Permalink
Provide Project via injection (#672)
Browse files Browse the repository at this point in the history
* Provide project via injection

* Move projectmodule to ctp package

* Move provider logic to provider class

* Move project related classes to same package

* Move application loader to application.conf where it belongs

* Disable sunrise modules for tests

* Provide i18n module to simple Play app for tests

* Fix test issue with missing modules

* Move localization classes back to package

* Add documentation

* Test static constructor projectContext
  • Loading branch information
lauraluiz authored Nov 7, 2017
1 parent a39f1df commit 924e28f
Show file tree
Hide file tree
Showing 30 changed files with 291 additions and 187 deletions.
37 changes: 0 additions & 37 deletions app/Module.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
import com.commercetools.sunrise.cms.CmsService;
import com.commercetools.sunrise.ctp.categories.CachedCategoryTreeProvider;
import com.commercetools.sunrise.ctp.categories.CategoriesSettings;
import com.commercetools.sunrise.ctp.categories.NavigationCategoryTree;
import com.commercetools.sunrise.ctp.categories.NewCategoryTree;
import com.commercetools.sunrise.email.EmailSender;
import com.commercetools.sunrise.framework.controllers.metrics.SimpleMetricsSphereClientProvider;
import com.commercetools.sunrise.framework.injection.RequestScoped;
import com.commercetools.sunrise.framework.localization.CountryFromSessionProvider;
import com.commercetools.sunrise.framework.localization.CurrencyFromCountryProvider;
import com.commercetools.sunrise.framework.localization.LocaleFromUrlProvider;
import com.commercetools.sunrise.framework.template.cms.FileBasedCmsServiceProvider;
import com.commercetools.sunrise.framework.template.engine.HandlebarsTemplateEngineProvider;
import com.commercetools.sunrise.framework.template.engine.TemplateEngine;
import com.commercetools.sunrise.framework.template.i18n.ConfigurableI18nResolverProvider;
import com.commercetools.sunrise.framework.template.i18n.I18nResolver;
import com.commercetools.sunrise.framework.viewmodels.content.carts.MiniCartViewModelFactory;
import com.commercetools.sunrise.httpauth.HttpAuthentication;
import com.commercetools.sunrise.httpauth.basic.BasicAuthenticationProvider;
Expand Down Expand Up @@ -61,11 +51,6 @@ public class Module extends AbstractModule {

@Override
protected void configure() {
// Binding for the client to connect commercetools
bind(SphereClient.class)
.toProvider(SimpleMetricsSphereClientProvider.class)
.in(Singleton.class);

// Binding for the HTTP Authentication
bind(HttpAuthentication.class)
.toProvider(BasicAuthenticationProvider.class)
Expand All @@ -74,33 +59,11 @@ protected void configure() {
// Binding for category tree
bind(CategoryTree.class).toProvider(CachedCategoryTreeProvider.class);

// Binding for all template related, such as the engine, CMS and i18n
bind(CmsService.class)
.toProvider(FileBasedCmsServiceProvider.class)
.in(Singleton.class);
bind(TemplateEngine.class)
.toProvider(HandlebarsTemplateEngineProvider.class)
.in(Singleton.class);
bind(I18nResolver.class)
.toProvider(ConfigurableI18nResolverProvider.class)
.in(Singleton.class);

// Bindings fo email sender
bind(EmailSender.class)
.toProvider(EmailSenderProvider.class)
.in(Singleton.class);

// Bindings for all user context related
bind(Locale.class)
.toProvider(LocaleFromUrlProvider.class)
.in(RequestScoped.class);
bind(CountryCode.class)
.toProvider(CountryFromSessionProvider.class)
.in(RequestScoped.class);
bind(CurrencyUnit.class)
.toProvider(CurrencyFromCountryProvider.class)
.in(RequestScoped.class);

// Bindings for the configured faceted search mappers
bind(TermFacetViewModelFactory.class)
.annotatedWith(Names.named("alphabeticallySorted"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.commercetools.sunrise.framework.viewmodels.SimpleViewModelFactory;
import com.commercetools.sunrise.framework.viewmodels.forms.countries.CountryFormSelectableOptionViewModel;
import com.commercetools.sunrise.framework.viewmodels.forms.countries.CountryFormSelectableOptionViewModelFactory;
import com.commercetools.sunrise.framework.localization.ProjectContext;
import com.commercetools.sunrise.ctp.project.ProjectContext;
import com.commercetools.sunrise.framework.injection.RequestScoped;
import com.neovisionaries.i18n.CountryCode;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

import javax.inject.Inject;

/**
* Provides a {@link SphereClientConfig} extracted from the application's configuration.
*/
public final class SphereClientConfigProvider implements Provider<SphereClientConfig> {

private static final String CONFIG_ROOT = "sunrise.ctp.client";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.commercetools.sunrise.ctp.client;

import com.commercetools.sunrise.framework.controllers.metrics.SimpleMetricsSphereClientProvider;
import com.google.inject.AbstractModule;
import io.sphere.sdk.client.SphereClient;
import io.sphere.sdk.client.SphereClientConfig;

import javax.inject.Singleton;

/**
* Module that allows to inject a {@link SphereClient} and its configuration.
*/
public final class SphereClientModule extends AbstractModule {

@Override
protected void configure() {
bind(SphereClientConfig.class)
.toProvider(SphereClientConfigProvider.class)
.in(Singleton.class);

bind(SphereClient.class)
.toProvider(SimpleMetricsSphereClientProvider.class)
.in(Singleton.class);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.commercetools.sunrise.framework.localization;
package com.commercetools.sunrise.ctp.project;

import com.commercetools.sunrise.framework.localization.NoCountryFoundException;
import com.commercetools.sunrise.framework.localization.NoCurrencyFoundException;
import com.commercetools.sunrise.framework.localization.NoLocaleFoundException;
import com.google.inject.ImplementedBy;
import com.neovisionaries.i18n.CountryCode;
import io.sphere.sdk.projects.Project;
import play.Configuration;

import javax.money.CurrencyUnit;
import java.util.List;
Expand Down Expand Up @@ -64,4 +69,8 @@ default boolean isCountrySupported(final CountryCode countryCode) {
default boolean isCurrencySupported(final CurrencyUnit currency) {
return currencies().contains(currency);
}

static ProjectContext of(final Configuration globalConfig, final String configPath, final Project project) {
return new ProjectContextImpl(globalConfig, configPath, project);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package com.commercetools.sunrise.framework.localization;
package com.commercetools.sunrise.ctp.project;

import com.commercetools.sunrise.play.configuration.SunriseConfigurationException;
import com.neovisionaries.i18n.CountryCode;
import io.sphere.sdk.client.SphereClient;
import io.sphere.sdk.client.SphereRequest;
import io.sphere.sdk.client.SphereTimeoutException;
import io.sphere.sdk.models.Base;
import io.sphere.sdk.projects.Project;
import io.sphere.sdk.projects.queries.ProjectGet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.Configuration;
Expand All @@ -16,12 +12,10 @@
import javax.inject.Singleton;
import javax.money.CurrencyUnit;
import javax.money.Monetary;
import java.time.Duration;
import java.util.List;
import java.util.Locale;
import java.util.function.Function;

import static io.sphere.sdk.client.SphereClientUtils.blockingWait;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;

Expand All @@ -34,26 +28,22 @@
final class ProjectContextImpl extends Base implements ProjectContext {

private static final Logger LOGGER = LoggerFactory.getLogger(ProjectContext.class);
private static final String CONFIG_LANGUAGES = "application.i18n.languages";
private static final String CONFIG_COUNTRIES = "application.countries";
private static final String CONFIG_CURRENCIES = "application.currencies";

private final List<Locale> locales;
private final List<CountryCode> countryCodes;
private final List<CurrencyUnit> currencies;

@Inject
ProjectContextImpl(final Configuration configuration, final SphereClient client) {
try {
final SphereRequest<Project> request = ProjectGet.of();
final Project project = blockingWait(client.execute(request), Duration.ofMinutes(1));
this.locales = projectLocales(configuration, project);
this.countryCodes = projectCountries(configuration, project);
this.currencies = projectCurrencies(configuration, project);
LOGGER.debug("Project Languages {}, Countries {}, Currencies {}", locales, countryCodes, currencies);
} catch (SphereTimeoutException e) {
throw new RuntimeException("Could not fetch project information", e);
}
ProjectContextImpl(final Configuration globalConfig, final Project project) {
this(globalConfig, "sunrise.ctp.project", project);
}

ProjectContextImpl(final Configuration globalConfig, final String configPath, final Project project) {
final Configuration config = globalConfig.getConfig(configPath);
this.locales = projectLocales(config, project);
this.countryCodes = projectCountries(config, project);
this.currencies = projectCurrencies(config, project);
LOGGER.debug("Initialized ProjectContext: Languages {}, Countries {}, Currencies {}", locales, countryCodes, currencies);
}

@Override
Expand All @@ -72,15 +62,15 @@ public List<CurrencyUnit> currencies() {
}

private static List<Locale> projectLocales(final Configuration configuration, final Project project) {
return getValues(configuration, CONFIG_LANGUAGES, Locale::forLanguageTag, project.getLanguageLocales());
return getValues(configuration, "languages", Locale::forLanguageTag, project.getLanguageLocales());
}

private static List<CountryCode> projectCountries(final Configuration configuration, final Project project) {
return getValues(configuration, CONFIG_COUNTRIES, CountryCode::getByCode, project.getCountries());
return getValues(configuration, "countries", CountryCode::getByCode, project.getCountries());
}

private static List<CurrencyUnit> projectCurrencies(final Configuration configuration, final Project project) {
return getValues(configuration, CONFIG_CURRENCIES, Monetary::getCurrency, project.getCurrencyUnits());
return getValues(configuration, "currencies", Monetary::getCurrency, project.getCurrencyUnits());
}

private static <T> List<T> getValues(final Configuration configuration, final String configKey,
Expand All @@ -94,4 +84,4 @@ private static <T> List<T> getValues(final Configuration configuration, final St
}
return values;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.commercetools.sunrise.ctp.project;

import com.google.inject.AbstractModule;
import io.sphere.sdk.projects.Project;

import javax.inject.Singleton;

/**
* Module that allows to inject a commercetools {@link Project}.
*/
public final class ProjectModule extends AbstractModule {

@Override
protected void configure() {
bind(Project.class)
.toProvider(ProjectProvider.class)
.in(Singleton.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.commercetools.sunrise.ctp.project;

import io.sphere.sdk.client.SphereClient;
import io.sphere.sdk.client.SphereRequest;
import io.sphere.sdk.projects.Project;
import io.sphere.sdk.projects.queries.ProjectGet;

import javax.inject.Inject;
import javax.inject.Provider;
import java.time.Duration;

import static io.sphere.sdk.client.SphereClientUtils.blockingWait;

/**
* Provides the commercetools {@link Project} associated with the injected {@link SphereClient}.
*/
public final class ProjectProvider implements Provider<Project> {

private final SphereClient sphereClient;

@Inject
ProjectProvider(final SphereClient sphereClient) {
this.sphereClient = sphereClient;
}

@Override
public Project get() {
final SphereRequest<Project> request = ProjectGet.of();
return blockingWait(sphereClient.execute(request), Duration.ofSeconds(30));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@

import static java.util.concurrent.CompletableFuture.completedFuture;

/**
* Provides a {@link SphereClient} using the {@link SimpleMetricsSphereClient} implementation.
*/
public final class SimpleMetricsSphereClientProvider implements Provider<SimpleMetricsSphereClient> {

private final ApplicationLifecycle applicationLifecycle;
private final SphereClientConfig sphereClientConfig;

@Inject
public SimpleMetricsSphereClientProvider(final ApplicationLifecycle applicationLifecycle, final SphereClientConfig sphereClientConfig) {
SimpleMetricsSphereClientProvider(final ApplicationLifecycle applicationLifecycle, final SphereClientConfig sphereClientConfig) {
this.applicationLifecycle = applicationLifecycle;
this.sphereClientConfig = sphereClientConfig;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package com.commercetools.sunrise.framework.injection;

import com.commercetools.sunrise.ctp.client.SphereClientConfigProvider;
import com.google.inject.AbstractModule;
import io.sphere.sdk.client.SphereClientConfig;
import io.sphere.sdk.utils.MoneyImpl;

import javax.inject.Singleton;
import javax.money.Monetary;
import javax.money.format.MonetaryFormats;

public class SunriseModule extends AbstractModule {
public final class SunriseModule extends AbstractModule {

@Override
protected void configure() {
applyJavaMoneyHack();
bindScope(RequestScoped.class, new RequestScope());
bind(SphereClientConfig.class).toProvider(SphereClientConfigProvider.class).in(Singleton.class);
}

private void applyJavaMoneyHack() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package com.commercetools.sunrise.framework.localization;

import com.commercetools.sunrise.ctp.project.ProjectContext;
import com.commercetools.sunrise.sessions.country.CountryInSession;
import com.neovisionaries.i18n.CountryCode;

import javax.inject.Inject;
import javax.inject.Provider;
import java.util.Optional;

/**
* Provides the {@link CountryCode} instance of the country saved in the user's session.
* If not set, it provides the default country from the project.
*/
public final class CountryFromSessionProvider implements Provider<CountryCode> {

private final ProjectContext projectContext;
private final CountryInSession countryInSession;

@Inject
public CountryFromSessionProvider(final ProjectContext projectContext, final CountryInSession countryInSession) {
CountryFromSessionProvider(final ProjectContext projectContext, final CountryInSession countryInSession) {
this.projectContext = projectContext;
this.countryInSession = countryInSession;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.commercetools.sunrise.framework.localization;

import com.commercetools.sunrise.ctp.project.ProjectContext;
import com.neovisionaries.i18n.CountryCode;

import javax.inject.Inject;
Expand All @@ -8,13 +9,16 @@
import javax.money.Monetary;
import java.util.Optional;

/**
* Provides the {@link CurrencyUnit} corresponding to the injected {@link CountryCode}.
*/
public final class CurrencyFromCountryProvider implements Provider<CurrencyUnit> {

private final CountryCode country;
private final ProjectContext projectContext;

@Inject
public CurrencyFromCountryProvider(final CountryCode country, final ProjectContext projectContext) {
CurrencyFromCountryProvider(final CountryCode country, final ProjectContext projectContext) {
this.country = country;
this.projectContext = projectContext;
}
Expand Down
Loading

0 comments on commit 924e28f

Please sign in to comment.