Decouple from the data-client service factory, with some code cleanup in the process (#5496)

This commit is contained in:
Paul Hawke 2024-01-29 16:46:01 -06:00 committed by GitHub
parent 7ec2a22fce
commit ab9e57f5be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 75 additions and 71 deletions

View file

@ -6,7 +6,6 @@ import fr.free.nrw.commons.kvstore.JsonKvStore;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import org.wikipedia.AppAdapter; import org.wikipedia.AppAdapter;
import org.wikipedia.dataclient.SharedPreferenceCookieManager; import org.wikipedia.dataclient.SharedPreferenceCookieManager;
import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.json.GsonMarshaller; import org.wikipedia.json.GsonMarshaller;
import org.wikipedia.json.GsonUnmarshaller; import org.wikipedia.json.GsonUnmarshaller;
@ -33,7 +32,7 @@ public class CommonsAppAdapter extends AppAdapter {
} }
@Override @Override
public OkHttpClient getOkHttpClient(@NonNull WikiSite wikiSite) { public OkHttpClient getOkHttpClient() {
return OkHttpConnectionFactory.getClient(); return OkHttpConnectionFactory.getClient();
} }

View file

@ -26,13 +26,10 @@ import androidx.core.app.NavUtils;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import fr.free.nrw.commons.auth.login.LoginClient; import fr.free.nrw.commons.auth.login.LoginClient;
import fr.free.nrw.commons.auth.login.LoginInterface;
import fr.free.nrw.commons.auth.login.LoginResult; import fr.free.nrw.commons.auth.login.LoginResult;
import fr.free.nrw.commons.databinding.ActivityLoginBinding; import fr.free.nrw.commons.databinding.ActivityLoginBinding;
import fr.free.nrw.commons.utils.ActivityUtils; import fr.free.nrw.commons.utils.ActivityUtils;
import java.util.Locale; import java.util.Locale;
import org.wikipedia.dataclient.ServiceFactory;
import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.dataclient.mwapi.MwQueryResponse; import org.wikipedia.dataclient.mwapi.MwQueryResponse;
import fr.free.nrw.commons.auth.login.LoginCallback; import fr.free.nrw.commons.auth.login.LoginCallback;
@ -57,7 +54,6 @@ import timber.log.Timber;
import static android.view.KeyEvent.KEYCODE_ENTER; import static android.view.KeyEvent.KEYCODE_ENTER;
import static android.view.View.VISIBLE; import static android.view.View.VISIBLE;
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE; import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
import static fr.free.nrw.commons.di.NetworkingModule.NAMED_COMMONS_WIKI_SITE;
public class LoginActivity extends AccountAuthenticatorActivity { public class LoginActivity extends AccountAuthenticatorActivity {

View file

@ -7,6 +7,7 @@ import dagger.Module;
import dagger.Provides; import dagger.Provides;
import fr.free.nrw.commons.BetaConstants; import fr.free.nrw.commons.BetaConstants;
import fr.free.nrw.commons.BuildConfig; import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.OkHttpConnectionFactory;
import fr.free.nrw.commons.actions.PageEditClient; import fr.free.nrw.commons.actions.PageEditClient;
import fr.free.nrw.commons.actions.PageEditInterface; import fr.free.nrw.commons.actions.PageEditInterface;
import fr.free.nrw.commons.actions.ThanksInterface; import fr.free.nrw.commons.actions.ThanksInterface;
@ -27,6 +28,7 @@ import fr.free.nrw.commons.review.ReviewInterface;
import fr.free.nrw.commons.upload.UploadInterface; import fr.free.nrw.commons.upload.UploadInterface;
import fr.free.nrw.commons.upload.WikiBaseInterface; import fr.free.nrw.commons.upload.WikiBaseInterface;
import fr.free.nrw.commons.upload.depicts.DepictsInterface; import fr.free.nrw.commons.upload.depicts.DepictsInterface;
import fr.free.nrw.commons.wikidata.CommonsServiceFactory;
import fr.free.nrw.commons.wikidata.WikidataInterface; import fr.free.nrw.commons.wikidata.WikidataInterface;
import java.io.File; import java.io.File;
import java.util.Locale; import java.util.Locale;
@ -39,7 +41,7 @@ import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor; import okhttp3.logging.HttpLoggingInterceptor;
import okhttp3.logging.HttpLoggingInterceptor.Level; import okhttp3.logging.HttpLoggingInterceptor.Level;
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient; import fr.free.nrw.commons.auth.csrf.CsrfTokenClient;
import org.wikipedia.dataclient.ServiceFactory; import org.wikipedia.AppAdapter;
import org.wikipedia.dataclient.WikiSite; import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.json.GsonUtil; import org.wikipedia.json.GsonUtil;
import fr.free.nrw.commons.auth.login.LoginClient; import fr.free.nrw.commons.auth.login.LoginClient;
@ -53,7 +55,6 @@ public class NetworkingModule {
public static final long OK_HTTP_CACHE_SIZE = 10 * 1024 * 1024; public static final long OK_HTTP_CACHE_SIZE = 10 * 1024 * 1024;
public static final String NAMED_COMMONS_WIKI_SITE = "commons-wikisite";
private static final String NAMED_WIKI_DATA_WIKI_SITE = "wikidata-wikisite"; private static final String NAMED_WIKI_DATA_WIKI_SITE = "wikidata-wikisite";
private static final String NAMED_WIKI_PEDIA_WIKI_SITE = "wikipedia-wikisite"; private static final String NAMED_WIKI_PEDIA_WIKI_SITE = "wikipedia-wikisite";
@ -75,6 +76,12 @@ public class NetworkingModule {
.build(); .build();
} }
@Provides
@Singleton
public CommonsServiceFactory serviceFactory() {
return new CommonsServiceFactory(AppAdapter.get().getOkHttpClient());
}
@Provides @Provides
@Singleton @Singleton
public HttpLoggingInterceptor provideHttpLoggingInterceptor() { public HttpLoggingInterceptor provideHttpLoggingInterceptor() {
@ -110,14 +117,14 @@ public class NetworkingModule {
@Provides @Provides
@Singleton @Singleton
public CsrfTokenInterface provideCsrfTokenInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) { public CsrfTokenInterface provideCsrfTokenInterface(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, CsrfTokenInterface.class); return serviceFactory.create(BuildConfig.COMMONS_URL, CsrfTokenInterface.class);
} }
@Provides @Provides
@Singleton @Singleton
public LoginInterface provideLoginInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) { public LoginInterface provideLoginInterface(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, LoginInterface.class); return serviceFactory.create(BuildConfig.COMMONS_URL, LoginInterface.class);
} }
@Provides @Provides
@ -142,13 +149,6 @@ public class NetworkingModule {
return HttpUrl.parse(TOOLS_FORGE_URL); return HttpUrl.parse(TOOLS_FORGE_URL);
} }
@Provides
@Singleton
@Named(NAMED_COMMONS_WIKI_SITE)
public WikiSite provideCommonsWikiSite() {
return new WikiSite(BuildConfig.COMMONS_URL);
}
@Provides @Provides
@Singleton @Singleton
@Named(NAMED_WIKI_DATA_WIKI_SITE) @Named(NAMED_WIKI_DATA_WIKI_SITE)
@ -169,40 +169,40 @@ public class NetworkingModule {
@Provides @Provides
@Singleton @Singleton
public ReviewInterface provideReviewInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) { public ReviewInterface provideReviewInterface(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, ReviewInterface.class); return serviceFactory.create(BuildConfig.COMMONS_URL, ReviewInterface.class);
} }
@Provides @Provides
@Singleton @Singleton
public DepictsInterface provideDepictsInterface(@Named(NAMED_WIKI_DATA_WIKI_SITE) WikiSite wikidataWikiSite) { public DepictsInterface provideDepictsInterface(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(wikidataWikiSite, BuildConfig.WIKIDATA_URL, DepictsInterface.class); return serviceFactory.create(BuildConfig.WIKIDATA_URL, DepictsInterface.class);
} }
@Provides @Provides
@Singleton @Singleton
public WikiBaseInterface provideWikiBaseInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) { public WikiBaseInterface provideWikiBaseInterface(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, WikiBaseInterface.class); return serviceFactory.create(BuildConfig.COMMONS_URL, WikiBaseInterface.class);
} }
@Provides @Provides
@Singleton @Singleton
public UploadInterface provideUploadInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) { public UploadInterface provideUploadInterface(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, UploadInterface.class); return serviceFactory.create(BuildConfig.COMMONS_URL, UploadInterface.class);
} }
@Named("commons-page-edit-service") @Named("commons-page-edit-service")
@Provides @Provides
@Singleton @Singleton
public PageEditInterface providePageEditService(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) { public PageEditInterface providePageEditService(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, PageEditInterface.class); return serviceFactory.create(BuildConfig.COMMONS_URL, PageEditInterface.class);
} }
@Named("wikidata-page-edit-service") @Named("wikidata-page-edit-service")
@Provides @Provides
@Singleton @Singleton
public PageEditInterface provideWikiDataPageEditService(@Named(NAMED_WIKI_DATA_WIKI_SITE) WikiSite wikiDataWikiSite) { public PageEditInterface provideWikiDataPageEditService(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(wikiDataWikiSite, BuildConfig.WIKIDATA_URL, PageEditInterface.class); return serviceFactory.create(BuildConfig.WIKIDATA_URL, PageEditInterface.class);
} }
@Named("commons-page-edit") @Named("commons-page-edit")
@ -215,8 +215,8 @@ public class NetworkingModule {
@Provides @Provides
@Singleton @Singleton
public MediaInterface provideMediaInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) { public MediaInterface provideMediaInterface(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, MediaInterface.class); return serviceFactory.create(BuildConfig.COMMONS_URL, MediaInterface.class);
} }
/** /**
@ -227,52 +227,44 @@ public class NetworkingModule {
*/ */
@Provides @Provides
@Singleton @Singleton
public WikidataMediaInterface provideWikidataMediaInterface( public WikidataMediaInterface provideWikidataMediaInterface(CommonsServiceFactory serviceFactory) {
@Named(NAMED_COMMONS_WIKI_SITE) final WikiSite commonsWikiSite) { return serviceFactory.create(BetaConstants.COMMONS_URL, WikidataMediaInterface.class);
return ServiceFactory.get(commonsWikiSite,
BetaConstants.COMMONS_URL, WikidataMediaInterface.class);
} }
@Provides @Provides
@Singleton @Singleton
public MediaDetailInterface providesMediaDetailInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikisite) { public MediaDetailInterface providesMediaDetailInterface(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(commonsWikisite, BuildConfig.COMMONS_URL, MediaDetailInterface.class); return serviceFactory.create(BuildConfig.COMMONS_URL, MediaDetailInterface.class);
} }
@Provides @Provides
@Singleton @Singleton
public CategoryInterface provideCategoryInterface( public CategoryInterface provideCategoryInterface(CommonsServiceFactory serviceFactory) {
@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) { return serviceFactory.create(BuildConfig.COMMONS_URL, CategoryInterface.class);
return ServiceFactory
.get(commonsWikiSite, BuildConfig.COMMONS_URL, CategoryInterface.class);
} }
@Provides @Provides
@Singleton @Singleton
public ThanksInterface provideThanksInterface( public ThanksInterface provideThanksInterface(CommonsServiceFactory serviceFactory) {
@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) { return serviceFactory.create(BuildConfig.COMMONS_URL, ThanksInterface.class);
return ServiceFactory
.get(commonsWikiSite, BuildConfig.COMMONS_URL, ThanksInterface.class);
} }
@Provides @Provides
@Singleton @Singleton
public NotificationInterface provideNotificationInterface( public NotificationInterface provideNotificationInterface(CommonsServiceFactory serviceFactory) {
@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) { return serviceFactory.create(BuildConfig.COMMONS_URL, NotificationInterface.class);
return ServiceFactory
.get(commonsWikiSite, BuildConfig.COMMONS_URL, NotificationInterface.class);
} }
@Provides @Provides
@Singleton @Singleton
public UserInterface provideUserInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) { public UserInterface provideUserInterface(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, UserInterface.class); return serviceFactory.create(BuildConfig.COMMONS_URL, UserInterface.class);
} }
@Provides @Provides
@Singleton @Singleton
public WikidataInterface provideWikidataInterface(@Named(NAMED_WIKI_DATA_WIKI_SITE) WikiSite wikiDataWikiSite) { public WikidataInterface provideWikidataInterface(CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(wikiDataWikiSite, BuildConfig.WIKIDATA_URL, WikidataInterface.class); return serviceFactory.create(BuildConfig.WIKIDATA_URL, WikidataInterface.class);
} }
/** /**
@ -281,8 +273,8 @@ public class NetworkingModule {
*/ */
@Provides @Provides
@Singleton @Singleton
public PageMediaInterface providePageMediaInterface(@Named(NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE) WikiSite wikiSite) { public PageMediaInterface providePageMediaInterface(@Named(NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE) WikiSite wikiSite, CommonsServiceFactory serviceFactory) {
return ServiceFactory.get(wikiSite, wikiSite.url(), PageMediaInterface.class); return serviceFactory.create(wikiSite.url(), PageMediaInterface.class);
} }
@Provides @Provides

View file

@ -0,0 +1,25 @@
package fr.free.nrw.commons.wikidata
import okhttp3.OkHttpClient
import org.wikipedia.json.GsonUtil
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
class CommonsServiceFactory(private val okHttpClient: OkHttpClient) {
private val builder: Retrofit.Builder by lazy {
// All instances of retrofit share this configuration, but create it lazily
Retrofit.Builder().client(okHttpClient)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(GsonUtil.getDefaultGson()))
}
private val retrofitCache: MutableMap<String, Retrofit> = mutableMapOf()
fun <T : Any> create(baseUrl: String, service: Class<T>): T = retrofitCache.getOrPut(baseUrl) {
// Cache instances of retrofit based on API backend
builder.baseUrl(baseUrl).build()
}.create(service)
}

View file

@ -1,7 +1,5 @@
package fr.free.nrw.commons; package fr.free.nrw.commons;
import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIPEDIA_URL;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import java.util.List; import java.util.List;
import java.util.concurrent.AbstractExecutorService; import java.util.concurrent.AbstractExecutorService;
@ -15,7 +13,6 @@ import org.junit.Before;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.wikipedia.AppAdapter; import org.wikipedia.AppAdapter;
import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.json.GsonUtil; import org.wikipedia.json.GsonUtil;
import retrofit2.Retrofit; import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.gson.GsonConverterFactory;
@ -27,7 +24,7 @@ public abstract class MockWebServerTest {
@Before public void setUp() throws Throwable { @Before public void setUp() throws Throwable {
AppAdapter.set(new TestAppAdapter()); AppAdapter.set(new TestAppAdapter());
OkHttpClient.Builder builder = AppAdapter.get().getOkHttpClient(new WikiSite(WIKIPEDIA_URL)).newBuilder(); OkHttpClient.Builder builder = AppAdapter.get().getOkHttpClient().newBuilder();
okHttpClient = builder.dispatcher(new Dispatcher(new ImmediateExecutorService())).build(); okHttpClient = builder.dispatcher(new Dispatcher(new ImmediateExecutorService())).build();
server.setUp(); server.setUp();
} }

View file

@ -5,7 +5,6 @@ import fr.free.nrw.commons.wikidata.WikidataConstants;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import org.wikipedia.AppAdapter; import org.wikipedia.AppAdapter;
import org.wikipedia.dataclient.SharedPreferenceCookieManager; import org.wikipedia.dataclient.SharedPreferenceCookieManager;
import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.dataclient.okhttp.TestStubInterceptor; import org.wikipedia.dataclient.okhttp.TestStubInterceptor;
import org.wikipedia.dataclient.okhttp.UnsuccessfulResponseInterceptor; import org.wikipedia.dataclient.okhttp.UnsuccessfulResponseInterceptor;
@ -22,7 +21,7 @@ public class TestAppAdapter extends AppAdapter {
} }
@Override @Override
public OkHttpClient getOkHttpClient(@NonNull WikiSite wikiSite) { public OkHttpClient getOkHttpClient() {
return new OkHttpClient.Builder() return new OkHttpClient.Builder()
.addInterceptor(new UnsuccessfulResponseInterceptor()) .addInterceptor(new UnsuccessfulResponseInterceptor())
.addInterceptor(new TestStubInterceptor()) .addInterceptor(new TestStubInterceptor())

View file

@ -3,7 +3,6 @@ package org.wikipedia;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.wikipedia.dataclient.SharedPreferenceCookieManager; import org.wikipedia.dataclient.SharedPreferenceCookieManager;
import org.wikipedia.dataclient.WikiSite;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@ -11,7 +10,7 @@ public abstract class AppAdapter {
public abstract String getMediaWikiBaseUrl(); public abstract String getMediaWikiBaseUrl();
public abstract String getRestbaseUriFormat(); public abstract String getRestbaseUriFormat();
public abstract OkHttpClient getOkHttpClient(@NonNull WikiSite wikiSite); public abstract OkHttpClient getOkHttpClient();
public abstract int getDesiredLeadImageDp(); public abstract int getDesiredLeadImageDp();
public abstract boolean isLoggedIn(); public abstract boolean isLoggedIn();

View file

@ -57,7 +57,7 @@ public final class ServiceFactory {
private static Retrofit createRetrofit(@NonNull WikiSite wiki, @NonNull String baseUrl) { private static Retrofit createRetrofit(@NonNull WikiSite wiki, @NonNull String baseUrl) {
return new Retrofit.Builder() return new Retrofit.Builder()
.client(AppAdapter.get().getOkHttpClient(wiki)) .client(AppAdapter.get().getOkHttpClient())
.baseUrl(baseUrl) .baseUrl(baseUrl)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(GsonUtil.getDefaultGson())) .addConverterFactory(GsonConverterFactory.create(GsonUtil.getDefaultGson()))

View file

@ -4,7 +4,6 @@ import androidx.annotation.NonNull;
import org.wikipedia.dataclient.Service; import org.wikipedia.dataclient.Service;
import org.wikipedia.dataclient.SharedPreferenceCookieManager; import org.wikipedia.dataclient.SharedPreferenceCookieManager;
import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.dataclient.okhttp.TestStubInterceptor; import org.wikipedia.dataclient.okhttp.TestStubInterceptor;
import org.wikipedia.dataclient.okhttp.UnsuccessfulResponseInterceptor; import org.wikipedia.dataclient.okhttp.UnsuccessfulResponseInterceptor;
import org.wikipedia.login.LoginResult; import org.wikipedia.login.LoginResult;
@ -24,7 +23,7 @@ public class TestAppAdapter extends AppAdapter {
} }
@Override @Override
public OkHttpClient getOkHttpClient(@NonNull WikiSite wikiSite) { public OkHttpClient getOkHttpClient() {
return new OkHttpClient.Builder() return new OkHttpClient.Builder()
.addInterceptor(new UnsuccessfulResponseInterceptor()) .addInterceptor(new UnsuccessfulResponseInterceptor())
.addInterceptor(new TestStubInterceptor()) .addInterceptor(new TestStubInterceptor())

View file

@ -8,8 +8,6 @@ import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.wikipedia.AppAdapter; import org.wikipedia.AppAdapter;
import org.wikipedia.TestAppAdapter; import org.wikipedia.TestAppAdapter;
import org.wikipedia.dataclient.Service;
import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.json.GsonUtil; import org.wikipedia.json.GsonUtil;
import okhttp3.Dispatcher; import okhttp3.Dispatcher;
@ -25,7 +23,7 @@ public abstract class MockWebServerTest {
@Before public void setUp() throws Throwable { @Before public void setUp() throws Throwable {
AppAdapter.set(new TestAppAdapter()); AppAdapter.set(new TestAppAdapter());
OkHttpClient.Builder builder = AppAdapter.get().getOkHttpClient(new WikiSite(Service.WIKIPEDIA_URL)).newBuilder(); OkHttpClient.Builder builder = AppAdapter.get().getOkHttpClient().newBuilder();
okHttpClient = builder.dispatcher(new Dispatcher(new ImmediateExecutorService())).build(); okHttpClient = builder.dispatcher(new Dispatcher(new ImmediateExecutorService())).build();
server.setUp(); server.setUp();
} }