How to create scheduler in EJB3.1 - scheduler

I am new to EJB3 world. I want to create scheduler for file processing in EJB. I tried the following code..
package com.fks.nclp.ejb.scheduler;
import javax.ejb.Schedule;
import javax.ejb.Schedules;
import javax.ejb.Stateless;
#Stateless
public class AutoTimerBean {
#Schedules(
{
#Schedule(second="3",persistent=false)
}
)
public void executeOnEveryTwoSecond(){
System.out.println("THIS IS TESTING OF EJB SCHEDULER");
}
}
And deployed EAR application on GlassFish3.1. As per my requirement the scheduler should be fired at every three seconds.
But its not happening. Any suggestion ???
Thanks,
Gunjan.

Got the solution. In GlassFish server, we have to create EJB timer service from admin console.
Steps are as follow ..
Go to glassFish admin console -> Go to Configurations
-> Go to server config -> Go to EJB Container
Here set Timer DataSource = JDBC Default Resource pool.
Restart the server.
After adding JDBC default resource pool to Timer DataSource, the scheduler works fine.
Thanks,
Gunjan.

Related

Unable to download embedded MongoDB, behind proxy, using automatic configuration script

I have a Spring Boot project, built using Maven, where I intend to use embedded mongo db. I am using Eclipse on Windows 7.
I am behind a proxy that uses automatic configuration script, as I have observed in the Connection tab of Internet Options.
I am getting the following exception when I try to run the application.
java.io.IOException: Could not open inputStream for https://downloads.mongodb.org/win32/mongodb-win32-i386-3.2.2.zip
at de.flapdoodle.embed.process.store.Downloader.downloadInputStream(Downloader.java:131) ~[de.flapdoodle.embed.process-2.0.1.jar:na]
at de.flapdoodle.embed.process.store.Downloader.download(Downloader.java:69) ~[de.flapdoodle.embed.process-2.0.1.jar:na]
....
MongoDB gets downloaded just fine, when I hit the following URL in my web browser:
https://downloads.mongodb.org/win32/mongodb-win32-i386-3.2.2.zip
This leads me to believe that probably I'm missing some configuration in my Eclipse or may be the maven project itself.
Please help me to find the right configuration.
What worked for me on a windows machine:
Download the zip file (https://downloads.mongodb.org/win32/mongodb-win32-i386-3.2.2.zip)
manually and put it (not unpack) into this folder:
C:\Users\<Username>\.embedmongo\win32\
Indeed the problem is about your proxy (a corporate one I guess).
If the proxy do not require authentication, you can solve your problem easily just by adding the appropriate -Dhttp.proxyHost=... and -Dhttp.proxyPort=... (or/and the same with "https.[...]") as JVM arguments in your eclipse junit Runner, as suggested here : https://github.com/learning-spring-boot/learning-spring-boot-2nd-edition-code/issues/2
One solution to your problem is to do the following.
Download MongoDB and place it on a ftp server which is inside your corporate network (for which you would not need proxy).
Then write a configuration in your project like this
#Bean
#ConditionalOnProperty("mongo.proxy")
public IRuntimeConfig embeddedMongoRuntimeConfig() {
final Command command = Command.MongoD;
final IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
.defaults(command)
.artifactStore(new ExtractedArtifactStoreBuilder()
.defaults(command)
.download(new DownloadConfigBuilder()
.defaultsForCommand(command)
.downloadPath("your-ftp-path")
.build())
.build())
.build();
return runtimeConfig;
}
With the property mongo.proxy you can control whether Spring Boot downloads MongoDB from your ftp server or from outside. If it is set to true then it downloads from the ftp server. If not then it tries to download from the internet.
The easiest way seems to me to customize the default configuration:
#Bean
DownloadConfigBuilderCustomizer mongoProxyCustomizer() {
return configBuilder -> {
configBuilder.proxyFactory(new HttpProxyFactory(host, port));
};
}
Got the same issue (with Spring Boot 2.6.1 the spring.mongodb.embedded.version property is mandatory).
To configure the proxy, I've added the configuration bean by myself:
#Value("${spring.mongodb.embedded.proxy.domain}")
private String proxyDomain;
#Value("${spring.mongodb.embedded.proxy.port}")
private Integer proxyPort;
#Bean
RuntimeConfig embeddedMongoRuntimeConfig(ObjectProvider<DownloadConfigBuilderCustomizer> downloadConfigBuilderCustomizers) {
Logger logger = LoggerFactory.getLogger(this.getClass().getPackage().getName() + ".EmbeddedMongo");
ProcessOutput processOutput = new ProcessOutput(Processors.logTo(logger, Slf4jLevel.INFO), Processors.logTo(logger, Slf4jLevel.ERROR), Processors.named("[console>]", Processors.logTo(logger, Slf4jLevel.DEBUG)));
return Defaults.runtimeConfigFor(Command.MongoD, logger).processOutput(processOutput).artifactStore(this.getArtifactStore(logger, downloadConfigBuilderCustomizers.orderedStream())).isDaemonProcess(false).build();
}
private ExtractedArtifactStore getArtifactStore(Logger logger, Stream<DownloadConfigBuilderCustomizer> downloadConfigBuilderCustomizers) {
de.flapdoodle.embed.process.config.store.ImmutableDownloadConfig.Builder downloadConfigBuilder = Defaults.downloadConfigFor(Command.MongoD);
downloadConfigBuilder.progressListener(new Slf4jProgressListener(logger));
downloadConfigBuilderCustomizers.forEach((customizer) -> {
customizer.customize(downloadConfigBuilder);
});
DownloadConfig downloadConfig = downloadConfigBuilder
.proxyFactory(new HttpProxyFactory(proxyDomain, proxyPort)) // <--- HERE
.build();
return Defaults.extractedArtifactStoreFor(Command.MongoD).withDownloadConfig(downloadConfig);
}
In my case, I had to add the HTTPS corporate proxy to Intellij Run Configuration.
Https because it was trying to download:
https://downloads.mongodb.org/win32/mongodb-win32-x86_64-4.0.2.zip
application.properties:
spring.data.mongodb.database=test
spring.data.mongodb.port=27017
spring.mongodb.embedded.version=4.0.2
Please keep in mind this is a (DEV) setup.

Cloud foundry spring boot data source pool configuration

I am using spring boot and use postgres , rabbit mq and deploying application on CF. We figured that we need to set connection pool, we found that whatever configuration we do, on CF we can its max 4 connections, not sure from where we get that number (probably something with buildpack or service config).
In order to resolve that I had to extend AbstractCloudConfig, and that is pain as it turns off other auto configuration so now I have to manually configure rabbit mq connection factory too:(. I have came up with below configuration, but not sure this is right way.
Spring boot version: 1.4
Please advise.
package com.example;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.config.java.AbstractCloudConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
/**
* If we need to modify some some custom service configuration on cloud foundry
* e.g. setting up of connection pools. If we set normally and expose bean, it
* will work fine on local machine. But as it will go to Cloud foundry it
* somehow creates max 4 connections. (Not sure from where this number comes)
*
* Adding this configuration meaning we no longer want to leverage auto
* configuration. As soon as Spring boot sees this bean in cloud profile it will
* turn of auto configuration. Expectation is application is going to take care
* of all configuration. This normally works for most of the applications.
*
* For more information read: https://github.com/dsyer/cloud-middleware-blog
* https://docs.cloudfoundry.org/buildpacks/java/spring-service-bindings.html
*
* Hopefully future release of spring boot will allow us to hijack only
* configuration that we want to do ourselves and rest will be auto
* configuration specifically in context with CloudFoundry.
*
*/
#Configuration
#Profile("cloud")
public class CloudServicesConfig extends AbstractCloudConfig {
#Value("${vcap.services.postgres.credentials.jdbc_uri}")
private String postgresUrl;
#Value("${vcap.services.postgres.credentials.username}")
private String postgresUsername;
#Value("${vcap.services.postgres.credentials.password}")
private String postgresPassword;
#Value("${spring.datasource.driver-class-name}")
private String dataSourceDriverClassName;
#Primary
#Bean
public DataSource dataSource() {
org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
dataSource.setDriverClassName(dataSourceDriverClassName);
dataSource.setUrl(postgresUrl);
dataSource.setUsername(postgresUsername);
dataSource.setPassword(postgresPassword);
dataSource.setInitialSize(10);
dataSource.setMaxIdle(5);
dataSource.setMinIdle(5);
dataSource.setMaxActive(25);
return dataSource;
}
// You can add rest of services configuration below e.g. rabbit connection
// factory, redis etc to centralize services configuration for cloud.
// This example did not use profile but that is what you should use to
// separate out cloud vs local configuraion to help run on local etc.
}
You don't need all that configuration just to customize the pool size. You should just need this code as shown in the documentation:
#Bean
public DataSource dataSource() {
PoolConfig poolConfig = new PoolConfig(5, 30, 3000);
DataSourceConfig dbConfig = new DataSourceConfig(poolConfig, null);
return connectionFactory().dataSource(dbConfig);
}

SOAP service in AEM 6.2

I'm trying to create a SOAP service in AEM 6.2 (the client cant make a REST call). Right now its up and works, the problem is when we redeploy or the AEM instance is reset... then the port of the service gets locked. Error on "create()".
final JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean();
jaxWsServerFactoryBean.setServiceClass(getWebServiceClass());
jaxWsServerFactoryBean.setAddress(this.webServiceAddress);
jaxWsServerFactoryBean.setServiceBean(this);
jaxWsServerFactoryBean.getInInterceptors().add(new LoggingInInterceptor());
jaxWsServerFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
server = jaxWsServerFactoryBean.create();
*ERROR* [OsgiInstallerImpl] org.apache.cxf.transport.http_jetty.JettyHTTPServerEngine Could not start Jetty server on port 4,517: Address already in use: bind
The first time I deploy works fine but then I have to change port for each redeploy... I'm closing the server if exists before that create, and if I call "isStarted()" it says false.
server.getDestination().shutdown();
server.stop();
server.destroy();
Really stuck for days on this, thank you for your help.
You should create a OSGI bundle and create your soap service inside the bundle.
#Activate
public void activate(BundleContext bundleContext) throws Exception {
... start your soap service
}
#Deactivate
public void deactivate() throws Exception {
... stop your soap service
}
Now you can restart your soap service by restarting the bundle. here is reference how to create a OSGI bundle. http://www.aemcq5tutorials.com/tutorials/create-osgi-bundle-in-aem/

annotation #RibbonClient not work together with RestTemplate

I am trying Ribbon configuration with RestTemplate based on bookmark service example but without luck, here is my code:
#SpringBootApplication
#RestController
#RibbonClient(name = "foo", configuration = SampleRibbonConfiguration.class)
public class BookmarkServiceApplication {
public static void main(String[] args) {
SpringApplication.run(BookmarkServiceApplication.class, args);
}
#Autowired
RestTemplate restTemplate;
#RequestMapping("/hello")
public String hello() {
String greeting = this.restTemplate.getForObject("http://foo/hello", String.class);
return String.format("%s, %s!", greeting);
}
}
with error page as below:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Mar 22 19:59:33 GMT+08:00 2016
There was an unexpected error (type=Internal Server Error, status=500).
No instances available for foo
but if I remove annotation #RibbonClient, everything will be just ok,
#RibbonClient(name = "foo", configuration = SampleRibbonConfiguration.class)
and here is SampleRibbonConfiguration implementation:
public class SampleRibbonConfiguration {
#Autowired
IClientConfig ribbonClientConfig;
#Bean
public IPing ribbonPing(IClientConfig config) {
return new PingUrl();
}
#Bean
public IRule ribbonRule(IClientConfig config) {
return new AvailabilityFilteringRule();
}
}
Is it because RibbonClient can not work with RestTemplate together?
and another question is that does Ribbon configuration like load balancing rule could be configured via application.yml configuration file?
as from Ribbon wiki, seems we can configure Ribbon parameters like NFLoadBalancerClassName, NFLoadBalancerRuleClassName etc in property file, does Spring Cloud also supports this?
I'm going to assume you're using Eureka for Service Discovery.
Your particular error:
No instances available for foo
can happen for a couple of reasons
1.) All services are down
All of the instances of your foo service could legitimately be DOWN.
Solution: Try visiting your Eureka Dashboard and ensure all the services are actually UP.
If you're running locally, the Eureka Dashboard is at http://localhost:8761/
2.) Waiting for heartbeats
When you very first register a service via Eureka, there's a period of time where the service is UP but not available. From the documentation
A service is not available for discovery by clients until the
instance, the server and the client all have the same metadata in
their local cache (so it could take 3 heartbeats)
Solution: Wait a good 30 seconds after starting your foo service before you try calling it via your client.
In your particular case I'm going to guess #2 is likely what's happening to you. You're probably starting the service and trying to call it immediately from the client.
When it doesn't work, you stop the client, make some changes and restart. By that time though, all of the heartbeats have completed and your service is now available.
For your second question. Look at the "Customizing the Ribbon Client using properties" section in the reference documentation. (link)

Determine web app path

I am using Spring Tool Suite (really eclipse). I just created a new springMVC project and created a simple controller. There was a problem with how STS created the project so I had to manually fix the groupID and artifactID in the pom. The problem I am currently having is I can't seem to hit my tomcat server (published and launched by STS). I have checked the directory structure in tomcat where it gets published and everything seems to be fine but I get 404's when I try and hit the controller. The tomcat logs look as if nothing has even tried to connect to it. They also show that my controller has been mapped:
2013-10-14 09:09:17.763] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/Login],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.verisk.underwriting.ims.web.IMSController.test()
This is what my controller looks like:
#Controller
#RequestMapping("Login")
public class IMSController
{
#RequestMapping(value = "", method = RequestMethod.GET)
#ResponseBody
public String test()
{
return "SUCCESS";
}
}
The app is called ims, so I should be able to hit this controller with this request:
http://localhost/ims/Login
It is configured with a java config (AppConfig.java):
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.some.package.ims.web")
public class AppConfig extends WebMvcConfigurerAdapter
{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
Is there a config file that specifies the base path for the app?
Have a look at the .metadata directory of our workspace. It has a .plugins folder, that constains the org.eclipse.wst.server.core directory, and there is one (or more) tmp0 diectory. That contains a wtpwebapps directory. This contains the deployed webapps with the name that is used -- for example MyApp.
<Workspace>\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\MyApp
Then your Login page is located at
http://localhost[:8080]/MyApp/Login
http://localhost/ims/Login will hit port 80 ; by default tomcat runs on port 8080. So unless you have changed tomcat's HTTP port to 80 you need to use localhost:8080
If the port is good then check that your application context path is really ims, by default it is the exact name of the generated WAR file. If you use WTP, eclipse "servers" view will show it under the server instance.
If the context path is good then check the configured URL mapping in your web.xml descriptor. Make sure you are not missing a prefix in the URL for REST/MVC servlet URL aggregation. In your case it looks like you should use .../resources/Login because your configured your resources to be under the /resources/** pattern.