MetricSupport and RegistryFactory can be accessed in any order now. (#457)

* MetricSupport and RegistryFactory can be accessed in any order now.

Signed-off-by: Tomas Langer <tomas.langer@oracle.com>

* Metrics refactoring continued - using a singleton
RegistryFactory and removed singleton from MetricsSupport.
Delayed initialization of registries in MetricsSupport to latest
possible moment.

Signed-off-by: Tomas Langer <tomas.langer@oracle.com>

* Checkstyle fixes.

Signed-off-by: Tomas Langer <tomas.langer@oracle.com>

* Fixes in statically initialized singleton.

Signed-off-by: Tomas Langer <tomas.langer@oracle.com>
This commit is contained in:
Tomas Langer
2019-02-28 18:30:38 +01:00
committed by GitHub
parent 9519558a08
commit 3adfa0d190
12 changed files with 174 additions and 109 deletions

View File

@@ -725,7 +725,7 @@ Add these declarations as private fields:
[source,java]
// _include::0-2:{greet-service}[tags=metricsRegistration;counterRegistration]
----
private final MetricRegistry registry = RegistryFactory.getRegistryFactory().get()
private final MetricRegistry registry = RegistryFactory.getInstance()
.getRegistry(MetricRegistry.Type.APPLICATION); // <1>
private final Counter greetCounter = registry.counter("accessctr"); // <2>
----

View File

@@ -73,7 +73,7 @@ public class GreetService implements Service {
* Create metric registry.
*/
// tag::metricsRegistration[]
private final MetricRegistry registry = RegistryFactory.getRegistryFactory().get()
private final MetricRegistry registry = RegistryFactory.getInstance()
.getRegistry(MetricRegistry.Type.APPLICATION); // <1>
// end::metricsRegistration[]

View File

@@ -82,7 +82,7 @@ public final class TodosHandler implements Service {
* @param bsc the {@code BackendServiceClient} to use
*/
public TodosHandler(BackendServiceClient bsc) {
MetricRegistry registry = RegistryFactory.getRegistryFactory().get().getRegistry(MetricRegistry.Type.APPLICATION);
MetricRegistry registry = RegistryFactory.getInstance().getRegistry(MetricRegistry.Type.APPLICATION);
this.bsc = bsc;
this.createCounter = registry.counter("created");

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -173,7 +173,7 @@ final class BaseRegistry extends Registry {
MetricUnits.NONE);
private final Config config;
protected BaseRegistry(Config config) {
private BaseRegistry(Config config) {
super(Type.BASE);
this.config = config;
}
@@ -185,32 +185,32 @@ final class BaseRegistry extends Registry {
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
// load all base metrics
register(result, config, MEMORY_USED_HEAP, (Gauge<Long>) () -> memoryBean.getHeapMemoryUsage().getUsed());
register(result, config, MEMORY_COMMITTED_HEAP, (Gauge<Long>) () -> memoryBean.getHeapMemoryUsage().getCommitted());
register(result, config, MEMORY_MAX_HEAP, (Gauge<Long>) () -> memoryBean.getHeapMemoryUsage().getMax());
register(result, MEMORY_USED_HEAP, (Gauge<Long>) () -> memoryBean.getHeapMemoryUsage().getUsed());
register(result, MEMORY_COMMITTED_HEAP, (Gauge<Long>) () -> memoryBean.getHeapMemoryUsage().getCommitted());
register(result, MEMORY_MAX_HEAP, (Gauge<Long>) () -> memoryBean.getHeapMemoryUsage().getMax());
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
register(result, config, JVM_UPTIME, (Gauge<Long>) runtimeBean::getUptime);
register(result, JVM_UPTIME, (Gauge<Long>) runtimeBean::getUptime);
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
register(result, config, THREAD_COUNT, (SimpleCounter) threadBean::getThreadCount);
register(result, config, THREAD_DAEMON_COUNT, (SimpleCounter) threadBean::getDaemonThreadCount);
register(result, config, THREAD_MAX_COUNT, (SimpleCounter) threadBean::getPeakThreadCount);
register(result, THREAD_COUNT, (SimpleCounter) threadBean::getThreadCount);
register(result, THREAD_DAEMON_COUNT, (SimpleCounter) threadBean::getDaemonThreadCount);
register(result, THREAD_MAX_COUNT, (SimpleCounter) threadBean::getPeakThreadCount);
ClassLoadingMXBean clBean = ManagementFactory.getClassLoadingMXBean();
register(result, config, CL_LOADED_COUNT, (SimpleCounter) clBean::getLoadedClassCount);
register(result, config, CL_LOADED_TOTAL, (SimpleCounter) clBean::getTotalLoadedClassCount);
register(result, config, CL_UNLOADED_COUNT, (SimpleCounter) clBean::getUnloadedClassCount);
register(result, CL_LOADED_COUNT, (SimpleCounter) clBean::getLoadedClassCount);
register(result, CL_LOADED_TOTAL, (SimpleCounter) clBean::getTotalLoadedClassCount);
register(result, CL_UNLOADED_COUNT, (SimpleCounter) clBean::getUnloadedClassCount);
OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
register(result, config, OS_AVAILABLE_CPU, (Gauge<Integer>) osBean::getAvailableProcessors);
register(result, config, OS_LOAD_AVERAGE, (Gauge<Double>) osBean::getSystemLoadAverage);
register(result, OS_AVAILABLE_CPU, (Gauge<Integer>) osBean::getAvailableProcessors);
register(result, OS_LOAD_AVERAGE, (Gauge<Double>) osBean::getSystemLoadAverage);
List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean gcBean : gcBeans) {
String poolName = gcBean.getName();
register(result, config, gcCountMeta(poolName), (Gauge<Long>) gcBean::getCollectionCount);
register(result, config, gcTimeMeta(poolName), (Gauge<Long>) gcBean::getCollectionTime);
register(result, gcCountMeta(poolName), (Gauge<Long>) gcBean::getCollectionCount);
register(result, gcTimeMeta(poolName), (Gauge<Long>) gcBean::getCollectionTime);
}
return result;
@@ -239,7 +239,6 @@ final class BaseRegistry extends Registry {
}
private static void register(BaseRegistry registry,
Config config,
Metadata meta,
Metric metric) {

View File

@@ -17,8 +17,10 @@
package io.helidon.metrics;
import java.util.Collections;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
@@ -80,34 +82,14 @@ import org.eclipse.microprofile.metrics.MetricUnits;
public final class MetricsSupport implements Service {
private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap());
private static final String DEFAULT_CONTEXT = "/metrics";
private final Registry base;
private final Registry app;
private final Registry vendor;
private final String context;
private final RegistryFactory rf;
private final Counter totalCount;
private final Meter totalMeter;
private static MetricsSupport metricsSupport;
private static final Logger LOGGER = Logger.getLogger(MetricsSupport.class.getName());
private MetricsSupport(Builder builder) {
this.rf = RegistryFactory.create(builder.config);
this.base = rf.getARegistry(MetricRegistry.Type.BASE);
this.app = rf.getARegistry(MetricRegistry.Type.APPLICATION);
this.vendor = rf.getARegistry(MetricRegistry.Type.VENDOR);
this.rf = builder.registryFactory.get();
this.context = builder.context;
this.totalCount = vendor.counter(new Metadata("requests.count",
"Total number of requests",
"Each request (regardless of HTTP method) will increase this counter",
MetricType.COUNTER,
MetricUnits.NONE));
this.totalMeter = vendor.meter(new Metadata("requests.meter",
"Meter for overall requests",
"Each request will mark the meter to see overall throughput",
MetricType.METERED,
MetricUnits.NONE));
}
/**
@@ -115,11 +97,8 @@ public final class MetricsSupport implements Service {
*
* @return a new instance built with default values (for context, base metrics enabled)
*/
public static synchronized MetricsSupport create() {
if (metricsSupport == null) {
metricsSupport = builder().build();
}
return metricsSupport;
public static MetricsSupport create() {
return MetricsSupport.builder().build();
}
/**
@@ -130,11 +109,8 @@ public final class MetricsSupport implements Service {
* configuration keys.
* @return a new instance configured withe config provided
*/
public static synchronized MetricsSupport create(Config config) {
if (metricsSupport == null) {
metricsSupport = builder().config(config).build();
}
return metricsSupport;
public static MetricsSupport create(Config config) {
return builder().config(config).build();
}
/**
@@ -157,7 +133,7 @@ public final class MetricsSupport implements Service {
boolean requestsJson = mediaType.isPresent() && mediaType.get().equals(MediaType.APPLICATION_JSON);
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("Generating metrics for media type " + mediaType.toString()
LOGGER.fine("Generating metrics for media type " + mediaType
+ ". requestsJson=" + requestsJson);
}
return requestsJson;
@@ -229,9 +205,8 @@ public final class MetricsSupport implements Service {
}
private static String checkMetricTypeThenRun(Metric metric, Function<HelidonMetric, String> fn) {
if (metric == null) {
throw new NullPointerException();
}
Objects.requireNonNull(metric);
if (!(metric instanceof HelidonMetric)) {
throw new IllegalArgumentException(String.format(
"Metric of type %s is expected to implement %s but does not",
@@ -278,6 +253,22 @@ public final class MetricsSupport implements Service {
@Override
public void update(Routing.Rules rules) {
Registry base = rf.getARegistry(MetricRegistry.Type.BASE);
Registry app = rf.getARegistry(MetricRegistry.Type.APPLICATION);
Registry vendor = rf.getARegistry(MetricRegistry.Type.VENDOR);
Counter totalCount = vendor.counter(new Metadata("requests.count",
"Total number of requests",
"Each request (regardless of HTTP method) will increase this counter",
MetricType.COUNTER,
MetricUnits.NONE));
Meter totalMeter = vendor.meter(new Metadata("requests.meter",
"Meter for overall requests",
"Each request will mark the meter to see overall throughput",
MetricType.METERED,
MetricUnits.NONE));
// register the metric registry and factory to be available to all
rules.any((req, res) -> {
req.context().register(app);
@@ -364,6 +355,7 @@ public final class MetricsSupport implements Service {
* A fluent API builder to build instances of {@link MetricsSupport}.
*/
public static final class Builder implements io.helidon.common.Builder<MetricsSupport> {
private Supplier<RegistryFactory> registryFactory;
private String context = DEFAULT_CONTEXT;
private Config config = Config.empty();
@@ -373,6 +365,9 @@ public final class MetricsSupport implements Service {
@Override
public MetricsSupport build() {
if (null == registryFactory) {
registryFactory = () -> RegistryFactory.getInstance(config);
}
return new MetricsSupport(this);
}
@@ -390,6 +385,23 @@ public final class MetricsSupport implements Service {
return this;
}
/**
* If you want to have mutliple registry factories with different endpoints, you may
* create them using {@link RegistryFactory#create(io.helidon.config.Config)} or
* {@link RegistryFactory#create()} and create multiple {@link io.helidon.metrics.MetricsSupport} instances
* with different {@link #context(String) contexts}.
* <p>
* If this method is not called, {@link io.helidon.metrics.MetricsSupport} would use the shared instance as
* provided by {@link io.helidon.metrics.RegistryFactory#getInstance(io.helidon.config.Config)}
*
* @param factory factory to use in this metric support
* @return updated builder instance
*/
public Builder registryFactory(RegistryFactory factory) {
registryFactory = () -> factory;
return this;
}
/**
* Set a new root context for REST API of metrics.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -210,14 +210,14 @@ class Registry extends MetricRegistry {
return type.getName();
}
Type registryType() {
return type;
}
public boolean empty() {
return allMetrics.isEmpty();
}
Type registryType() {
return type;
}
private <T extends Metric> MetricImpl toImpl(Metadata metadata, T metric) {
switch (metadata.getTypeRaw()) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
package io.helidon.metrics;
import java.util.EnumMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import io.helidon.config.Config;
@@ -26,15 +27,28 @@ import org.eclipse.microprofile.metrics.MetricRegistry.Type;
/**
* Access point to all registries.
* Note that the first registry to be created (this is expected to be the one created by
* Web Server integration or by Microprofile integration) is the static instance to be used
* by all CDI integrations (and by all using the static {@link #getRegistryFactory()}.
*
* There are two options to use the factory:
* <ol>
* <li>A singleton instance, obtained through {@link #getInstance()} or {@link #getInstance(io.helidon.config.Config)}.
* This instance is lazily initialized - the latest call that provides a config instance before a
* {@link org.eclipse.microprofile.metrics.MetricRegistry.Type#BASE} registry is obtained would be used to configure
* the base registry (as that is the only configurable registry in current implementation)
* </li>
* <li>A custom instance, obtained through {@link #create(Config)} or {@link #create()}. This would create a
* new instance of a registry factory (in case multiple instances are desired), independent on the singleton instance
* and on other instances provided by these methods.</li>
* </ol>
* <p>
*/
// this class is not immutable, as we may need to update registries with configuration post creation
// see Github issue #360
public final class RegistryFactory {
private static volatile RegistryFactory staticInstance;
private static final RegistryFactory INSTANCE = create();
private final EnumMap<Type, Registry> registries = new EnumMap<>(Type.class);
private final EnumMap<Type, Registry> publicRegistries = new EnumMap<>(Type.class);
private final AtomicReference<Config> config;
private RegistryFactory(Config config) {
Registry registry = Registry.create(Type.APPLICATION);
@@ -45,36 +59,45 @@ public final class RegistryFactory {
registries.put(Type.VENDOR, registry);
publicRegistries.put(Type.VENDOR, FinalRegistry.create(registry));
registry = BaseRegistry.create(config);
registries.put(Type.BASE, registry);
publicRegistries.put(Type.BASE, FinalRegistry.create(registry));
this.config = new AtomicReference<>(config);
}
static synchronized RegistryFactory create(Config config) {
RegistryFactory factory = new RegistryFactory(config);
if (null == staticInstance) {
staticInstance = factory;
}
return factory;
}
static RegistryFactory create() {
/**
* Create a new factory with default configuration, with pre-filled
* {@link org.eclipse.microprofile.metrics.MetricRegistry.Type#VENDOR} and
* {@link org.eclipse.microprofile.metrics.MetricRegistry.Type#BASE} metrics.
*
* @return a new registry factory
*/
public static RegistryFactory create() {
return create(Config.empty());
}
/**
* Get a supplier for registry factory. The supplier will return the first
* instance that is created (this is assumed to be the one created by
* user when creating a registry factory).
* If you decide to use multiple registry factories, make sure that the first
* one created is the one to be accessed from a static context (e.g. from CDI).
* Create a new factory with provided configuration, with pre filled
* {@link org.eclipse.microprofile.metrics.MetricRegistry.Type#VENDOR} and
* {@link org.eclipse.microprofile.metrics.MetricRegistry.Type#BASE} metrics.
*
* @param config configuration to use
* @return a new registry factory
*/
public static RegistryFactory create(Config config) {
return new RegistryFactory(config);
}
/**
* Get a supplier for registry factory. The supplier will return the singleton isntance
* that is created.
*
* @return supplier of registry factory (to bind as late as possible)
* @deprecated use {@link io.helidon.metrics.RegistryFactory#getInstance() RegistryFactory::getInstance} instead.
*/
@Deprecated
public static Supplier<RegistryFactory> getRegistryFactory() {
return () -> staticInstance;
return RegistryFactory::getInstance;
}
/**
@@ -82,12 +105,40 @@ public final class RegistryFactory {
*
* @param config configuration to load the factory config from
* @return a new registry factory to obtain application registry (and other registries)
* @deprecated use {@link #create()} or {@link #create(io.helidon.config.Config)} instead when a new
* registry factory instance is needed. Use {@link #getInstance()} or {@link #getInstance(io.helidon.config.Config)}
* to retrieve the shared (singleton) instance.
*/
@Deprecated
public static RegistryFactory createSeFactory(Config config) {
return create(config);
}
/**
* Get a singleton instance of the registry factory.
*
* @return registry factory singleton
*/
public static RegistryFactory getInstance() {
return INSTANCE;
}
/**
* Get a singleton instance of the registry factory for and update it with provided configuration.
* Note that the config is used only if nobody access the base registry.
*
* @param config configuration of the registry factory used to update behavior of the instance returned
* @return registry factory singleton
*/
public static RegistryFactory getInstance(Config config) {
INSTANCE.update(config);
return INSTANCE;
}
Registry getARegistry(Type type) {
if (type == Type.BASE) {
ensureBase();
}
return registries.get(type);
}
@@ -100,6 +151,22 @@ public final class RegistryFactory {
* @return Registry for the type defined.
*/
public MetricRegistry getRegistry(Type type) {
if (type == Type.BASE) {
ensureBase();
}
return publicRegistries.get(type);
}
private void update(Config config) {
this.config.set(config);
}
private synchronized void ensureBase() {
if (null == registries.get(Type.BASE)) {
Registry registry = BaseRegistry.create(config.get());
registries.put(Type.BASE, registry);
publicRegistries.put(Type.BASE, FinalRegistry.create(registry));
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ class MetricsSupportTest {
@BeforeAll
static void initClass() {
RegistryFactory rf = RegistryFactory.create();
RegistryFactory rf = RegistryFactory.getInstance();
base = rf.getARegistry(MetricRegistry.Type.BASE);
vendor = rf.getARegistry(MetricRegistry.Type.VENDOR);
app = rf.getARegistry(MetricRegistry.Type.APPLICATION);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,8 +49,6 @@ import javax.enterprise.inject.spi.configurator.AnnotatedTypeConfigurator;
import javax.inject.Qualifier;
import javax.interceptor.Interceptor;
import io.helidon.metrics.MetricsSupport;
import org.eclipse.microprofile.metrics.Counter;
import org.eclipse.microprofile.metrics.Histogram;
import org.eclipse.microprofile.metrics.Metadata;
@@ -161,7 +159,6 @@ public class MetricsCdiExtension implements Extension {
LOGGER.log(Level.FINE, () -> "### Before bean discovery " + discovery);
// Initialize our implementation
MetricsSupport.create();
RegistryProducer.clearApplicationRegistry();
// Register beans manually

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
package io.helidon.microprofile.metrics;
import java.util.function.Supplier;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
@@ -31,9 +29,8 @@ import org.eclipse.microprofile.metrics.annotation.RegistryType;
* Producer of each type of registry.
*/
@ApplicationScoped
public class RegistryProducer {
private static Supplier<RegistryFactory> factorySupplier = RegistryFactory.getRegistryFactory();
public final class RegistryProducer {
private static final RegistryFactory REGISTRY_FACTORY = RegistryFactory.getInstance();
private RegistryProducer() {
}
@@ -46,19 +43,19 @@ public class RegistryProducer {
@Produces
@RegistryType(type = Type.APPLICATION)
public static MetricRegistry getApplicationRegistry() {
return factorySupplier.get().getRegistry(Type.APPLICATION);
return REGISTRY_FACTORY.getRegistry(Type.APPLICATION);
}
@Produces
@RegistryType(type = Type.BASE)
public static MetricRegistry getBaseRegistry() {
return factorySupplier.get().getRegistry(Type.BASE);
return REGISTRY_FACTORY.getRegistry(Type.BASE);
}
@Produces
@RegistryType(type = Type.VENDOR)
public static MetricRegistry getVendorRegistry() {
return factorySupplier.get().getRegistry(Type.VENDOR);
return REGISTRY_FACTORY.getRegistry(Type.VENDOR);
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,9 +20,6 @@ import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;
import javax.enterprise.inject.spi.CDI;
import io.helidon.metrics.MetricsSupport;
import io.helidon.microprofile.metrics.MetricsCdiExtension;
import org.eclipse.microprofile.metrics.Metric;
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.junit.jupiter.api.AfterAll;
@@ -45,7 +42,6 @@ public class MetricsBaseTest {
@BeforeAll
public synchronized static void startCdiContainer() {
MetricsSupport.create(); // needed by metrics CDI
final SeContainerInitializer initializer = SeContainerInitializer.newInstance();
assertThat(initializer, is(notNullValue()));
cdiContainer = initializer.initialize();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package io.helidon.microprofile.metrics;
import javax.enterprise.inject.spi.CDI;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
@@ -30,8 +29,6 @@ import org.eclipse.microprofile.metrics.Metadata;
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.MetricType;
import org.eclipse.microprofile.metrics.MetricUnits;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
@@ -59,7 +56,7 @@ public class MetricsMpServiceTest {
.build();
server.start();
registry = RegistryFactory.getRegistryFactory().get().getRegistry(MetricRegistry.Type.APPLICATION);
registry = RegistryFactory.getInstance().getRegistry(MetricRegistry.Type.APPLICATION);
port = server.port();
baseUri = "http://localhost:" + port;