Eureka client looking for default url instead of custom url - java

I have eureka server that posted in tomcat server (localhost:80/eureka-server)
spring.application.name=eureka
server.port=80
server.servlet.context-path=/eureka-server
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.default-zone=http://localhost:80/eureka-server/eureka/
#SpringBootApplication
#EnableEurekaServer
public class EurekaServer extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
}
In my microservice i try to register it in eureka
spring.application.name=randomService
eureka.client.service-url.default-zone=http://localhost:80/eureka-server/eureka/
#SpringBootApplication
#EnableEurekaClient
public class RandomServiceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(RandomServiceApplication.class, args);
}
}
but everytime microservice tries to connect with default eureka url (http://localhost:8761). What should i do?

So, i solved it in unusual way, in my microservice i changed application.properties
eureka.client.service-url.default-zone=...
to camelCase
eureka.client.serviceUrl.defaultZone=

Related

How does logging into the console works in the Java Spring framework

I have a very simple Spring application, but I can't not get a System.out.println statement to print into the console.
This is the main app file where I am printing an env variable set in a .yml file
import path.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class MainApplication {
#Autowired
private Config config;
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MainApplication.class);
app.run();
}
public void run(String... args) throws Exception {
System.out.println("env: " + config.getEnv());
}
}
The configuration file looks like this:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableConfigurationProperties
#ConfigurationProperties
public class Config {
private String env;
public void setEnv(String env) {
this.env = env;
}
public String getEnv() {
return this.env;
}
}
Finally the properties yml file
spring:
profiles.active: dev
h2:
console:
enabled: true
---
spring:
profiles: dev
env: dev
---
spring:
profiles: test
env: test
---
spring:
profiles: prod
env: prod
The Spring app builds a runs fine, however, I can't see the env variable to show in the terminal. I have seen examples of people using Controllers with a Request endpoint just to debug the environment variables in the browser. Is that the only option?
Couple of changes to your code, you don't need to use new keyword for starting spring application, you can directly use static run method
public static void main(String[] args) {
SpringApplication.run(MainApplication.class);
}
Second thing the run method in MainApplication will only execute if that class implements CommandLineRunner
#SpringBootApplication
public class MainApplication implements CommandLineRunner {
#Autowired
private Config config;
public static void main(String[] args) {
SpringApplication.run(MainApplication.class);
}
public void run(String... args) throws Exception {
System.out.println("env: " + config.getEnv());
}
}

Spring Boot can connect to Cassandra when running as Servlet but not as Command Line

Background: I'm trying to set up a code-based data migration system for our Cassandra database. I don't have a ton of experience with Java, but if this were a .NET project I'd set up the migrations as a different project under the same solution. However, based on guidance from other team members that are more experienced, it was recommended that I include the migrations in the same package as the rest of the application (which I'm fine with). It was also suggested that the easiest method would be to run the migrations via a web API endpoint (which I'm more skeptical of). In the interest of avoiding opening up a potential security vulnerability, I thought I'd take a shot at making a command-line utility to execute the migrations.
I have a Spring Boot web application with an entry point class that looks like this:
#Configuration
#SpringBootApplication
#EnableAutoConfiguration
#EnableCaching
#EnableScheduling
public class MyApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
public static void main(String[] args) {
new MyApplication().configure(new SpringApplicationBuilder(MyApplication.class)).run(args);
}
}
However, I'm trying to add the functionality to run a couple migration scripts that are packaged with this application via the command line (e.g. java -jar MyApplication.jar migrate), so I added the following class:
#Configuration
#SpringBootApplication
#EnableAutoConfiguration
public class MigrationRunner implements CommandLineRunner {
#Autowired
Session session;
#Override
public void run(String[] args)
{
MigrationResources mr = new MigrationResources();
mr.addMigration(...);
mr.addMigration(...);
MigrationEngine.withSession(session).migrate(mr);
}
}
And then updated my entry point class like this:
// annotations
public class MyApplication extends SpringBootServletInitializer {
private final static String MIGRATE_COMMAND = "migrate";
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
public static void main(String[] args) {
if (args.length > 0 && args[0].equalsIgnoreCase(MIGRATE_COMMAND)) {
new SpringApplicationBuilder()
.sources(MigrationRunner.class)
.run(Arrays.copyOfRange(args, 1, args.length));
} else {
new MyApplication().configure(new SpringApplicationBuilder(MyApplication.class)).run(args);
}
}
}
The problem is that when I execute this with the migrate arg, Spring throws this error:
Error creating bean with name 'migrationRunner': Unsatisfied dependency expressed through field 'session'
Error creating bean with name 'session' defined in class path resource [org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfiguration.class]: Invocation of init method failed
All host(s) tried for query failed (tried: server022/XX.YY.ZZ.022:9042 (com.datastax.driver.core.exceptions.TransportException: [server022/XX.YY.ZZ.022:9042] Connection has been closed), server022/XX.YY.ZZ.020:9042 (com.datastax.driver.core.exceptions.TransportException: [server020/XX.YY.ZZ.020:9042] Connection has been closed), server020/XX.YY.ZZ.021:9042 (com.datastax.driver.core.exceptions.TransportException: [server020/XX.YY.ZZ.021:9042] Connection has been closed))
Running it without the migrate arg still works fine. I suspect that Spring is simply not picking up the correct certificates for this Cassandra server, even though it appears to be getting all the other configuration properties (server name, keyspace, etc.)
Question: How can I make a Spring Boot servlet that also has a command-line mode and can connect to the configured Cassandra server in both modes?
All you need to do is,
#SpringBootApplication
public class MyApplication
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
You have over complicated the application. If you run the MyApplication.main that will run in port 8080 by default.
Bonus, If you need both to start from same class.
#SpringBootApplication
public class MigrationRunner implements CommandLineRunner {
#Autowired
Session session;
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
#Override
public void run(String[] args)
{
MigrationResources mr = new MigrationResources();
mr.addMigration(...);
mr.addMigration(...);
MigrationEngine.withSession(session).migrate(mr);
}
}

Spring Boot renaming server.port in application.properties

I have a spring boot server app in my src/test folder that is configured to run with my test.properties.
Currently my properties looks like this:
server.port=9119
server.ssl.enabled=false
logging.config=classpath:logback-spring.xml
logging.file=messages
logging.file.max-size=50MB
logging.level.com.nulogix=DEBUG
billing.engine.address=127.0.0.1
billing.engine.port=9119
billing.engine.api.version=0.97
billing.engine.core.version=0.97
billing.engine.core.name=Patient_Responsibility
I want to retire server.port and point my server to get the port from billing.engine.port.
Is it possible to configure Spring to do this?
My spring app main class currently looks like this
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
#SpringBootApplication
public class MockServerApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
new SpringApplicationBuilder(MockServerApp.class)
.properties("spring.config.name:test")
.build()
.run(args);
}
}
you can use this code
#Component
public class ServerPortCustomizer
implements WebServerFactoryCustomizer<ConfigurableWebServerFactory> {
#Value("${billing.engine.port}")
private String SERVERPORTNO;
#Override
public void customize(ConfigurableWebServerFactory factory) {
factory.setPort(SERVERPORTNO);
}
}
and also change your application.properties
#server.port=9119
billing.engine.port=9119
it's not a tested code.... I am writing this code based on my knowledge

Are there anyway to disable annotation in spring4?

I have a question, maybe simple, but I can not find out the solution.
I am using spring boot and added some annotation to the code like this:
#EnableEurekaClient
#SpringBootApplication
#EnableCaching
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
But in some other environment, for example, in production environment, we want to remove EurekaClient, but I do not want to manually remove it manually for each environment, instead, I want to use environment variable or command line parameter to control the behavior. I suppose to do this way:
#EnableEurekaClient(Enabled = {EnableEureka})
#SpringBootApplication
#EnableCaching
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Then I can easily start this application without touching the code.
Can anyone tell me if this is possible? If so, how can I do it?
Thanks
You would want to work with Spring Boot Profiles. Split out the #EnableEurekaClient to another #Configuration class and also add an #Profile("eureka-client") to the class. Then when starting up the application you can set a -Dspring.profiles.active=eureka-client for the environments other than production.
Example:
#SpringBootApplication
#EnableCaching
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
#Configuration
#EnableEurekaClient
#Profile("eureka-client")
public class EurekaClientConfiguration {
}
I prefer this method as you don't have to create an extra profile:
#Configuration
#EnableEurekaClient
#ConditionalOnProperty(name = "application.enabled", havingValue = "true", matchIfMissing = false)
public class EurekaClientConfiguration {
}

Finding app base for embedded tomcat in spring boot

I am using spring boot. I am developing a web application and i need to get the app base to generate a link for an email. For that i need to get the base URL. As the tomcat is embedded
request.getContextpath()
returns null. I need to get that localhost:8080 dynamically so that when I deploy this to server I don't have to change the code.
In a spring boot application you can change the server context in the application.properties with the properties server.context-path=your-path
in your code you can refer to this properties like below
#SpringBootApplication
#EnableConfigurationProperties(ServerProperties.class)
public class DemoApplication implements CommandLineRunner{
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Autowired
ServerProperties serverProperties;
#Override
public void run(String... strings) throws Exception {
System.out.println("serverProperties.getContextPath(): " + serverProperties.getContextPath());
}
}
The key point here is use #EnableConfigurationProperties(ServerProperties.class) on your #Configuration class and then use the injected fiels ServerProperties for consume the value.
I hope that this can help you...
Huh, that took me some time to get there but:
#SpringBootApplication
public class TestServiceApplication {
public static void main(String[] args) {
AnnotationConfigEmbeddedWebApplicationContext context = (AnnotationConfigEmbeddedWebApplicationContext)SpringApplication.run(TestServiceApplication.class, args);
TomcatEmbeddedServletContainer tomcatContainer = (TomcatEmbeddedServletContainer)context.getEmbeddedServletContainer();
String host = tomcatContainer.getTomcat().getHost().getName();
int port = tomcatContainer.getPort();
System.out.println("Host:port " + host + ":" + port);
}
}
Output: Host:port localhost:8080
Is that what You wanted?

Categories