Hi Everyone: My bundle osgi installed into karaf container 4.0.7, that use camel-quartz2-2.17.3 In camelContext I have many routes such as "myRoute", it call a job quatrz (using camel-quartz2) configured in postgresql database:
-------------------------------------------------------------------------------------------- Camel route -------------------------------------------------------------------------------------------- <camelContext id="myCamelContext" xmlns="http://camel.apache.org/schema/blueprint"> <route id="myRoute"> <from uri="quartz2://statGroup/startupTimer?cron={{stat.purge.wan.volume.daily.dc}}" /> <bean ref="myProcessor" method="myMethod" /> </route> </camelContext> -------------------------------------------------------------------------------------------- Bean quartz2 -------------------------------------------------------------------------------------------- <bean id="quartz2" class="org.apache.camel.component.quartz2.QuartzComponent"> <property name="propertiesFile" value="file:etc/stat_quartz.cfg" /> </bean> -------------------------------------------------------------------------------------------- quartz2 configuration : stat_quartz.cfg -------------------------------------------------------------------------------------------- #============================================================================ # Configure Main Scheduler Properties #============================================================================ org.quartz.scheduler.instanceName=Scheduler org.quartz.scheduler.instanceId=AUTO org.quartz.scheduler.skipUpdateCheck=true org.quartz.scheduler.jobFactory.class=org.quartz.simpl.SimpleJobFactory #============================================================================ # Configure ThreadPool #============================================================================ org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount=10 #============================================================================ # Configure JobStore #============================================================================ org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate org.quartz.jobStore.dataSource=statQuartzDS org.quartz.jobStore.tablePrefix=stat_qrtz_ org.quartz.jobStore.isClustered=true org.quartz.jobStore.clusterCheckinInterval=20000 org.quartz.jobStore.useProperties=false #============================================================================ # Configure Datasources #============================================================================ org.quartz.dataSource.statQuartzDS.jndiURL=osgi:service/statQuartzDS -------------------------------------------------------------------------------------------- Problem -------------------------------------------------------------------------------------------- My issue is when I try to starting the karaf container and postgresql is stopped, I have the log problem below and the camelContext "myCamelContext" will be shutdown. 2016-10-14 17:21:40,201 | ERROR | FelixStartLevel | BlueprintCamelContext | 80 - org.apache.camel.camel-blueprint - 2.17.3 | Error occurred during starting Camel: CamelContext(statisticsContext) due Failed to create route myRoute: Route(myRoute)[[From[quartz2://stat... because of Failed to resolve endpoint: quartz2://statGroup/startupTimer?trigger.repeatCount=0&trigger.repeatInterval=1 due to: Failed to obtain DB connection from data source 'statQuartzDS': java.sql.SQLException: Could not retrieve datasource via JNDI url 'osgi:service/statQuartzDS' java.sql.SQLException: Unable to acquire a new connection from the pool org.apache.camel.FailedToCreateRouteException: Failed to create route myRoute: Route(myRoute)[[From[quartz2://stat... because of Failed to resolve endpoint: quartz2://statGroup/startupTimer?trigger.repeatCount=0&trigger.repeatInterval=1 due to: Failed to obtain DB connection from data source 'statQuartzDS': java.sql.SQLException: Could not retrieve datasource via JNDI url 'osgi:service/statQuartzDS' java.sql.SQLException: Unable to acquire a new connection from the pool at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:201) at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:974)[83:org.apache.camel.camel-core:2.17.3] at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:3301)[83:org.apache.camel.camel-core:2.17.3] at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3024)[83:org.apache.camel.camel-core:2.17.3] at org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:175)[83:org.apache.camel.camel-core:2.17.3] at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2854) at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2850) at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:2873)[83:org.apache.camel.camel-core:2.17.3] at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:2850)[83:org.apache.camel.camel-core:2.17.3] at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61) at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:2819)[83:org.apache.camel.camel-core:2.17.3] at org.apache.camel.blueprint.BlueprintCamelContext.start(BlueprintCamelContext.java:180) at org.apache.camel.blueprint.BlueprintCamelContext.maybeStart(BlueprintCamelContext.java:212) at org.apache.camel.blueprint.BlueprintCamelContext.serviceChanged(BlueprintCamelContext.java:150) at org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:991)[org.apache.felix.framework-5.4.0.jar:] at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:839)[org.apache.felix.framework-5.4.0.jar:] at org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:546)[org.apache.felix.framework-5.4.0.jar:] at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4557)[org.apache.felix.framework-5.4.0.jar:] at org.apache.felix.framework.Felix.registerService(Felix.java:3549)[org.apache.felix.framework-5.4.0.jar:] at org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:348) at org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:355) at org.apache.camel.blueprint.BlueprintCamelContext.init(BlueprintCamelContext.java:100) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.8.0_101] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)[:1.8.0_101] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_101] at java.lang.reflect.Method.invoke(Method.java:498)[:1.8.0_101] at org.apache.aries.blueprint.utils.ReflectionUtils.invoke(ReflectionUtils.java:299)[12:org.apache.aries.blueprint.core:1.6.2] at org.apache.aries.blueprint.container.BeanRecipe.invoke(BeanRecipe.java:980)[12:org.apache.aries.blueprint.core:1.6.2] at org.apache.aries.blueprint.container.BeanRecipe.runBeanProcInit(BeanRecipe.java:736)[12:org.apache.aries.blueprint.core:1.6.2] at org.apache.aries.blueprint.container.BeanRecipe.internalCreate2(BeanRecipe.java:848)[12:org.apache.aries.blueprint.core:1.6.2] at org.apache.aries.blueprint.container.BeanRecipe.internalCreate(BeanRecipe.java:811)[12:org.apache.aries.blueprint.core:1.6.2] at org.apache.aries.blueprint.di.AbstractRecipe$1.call(AbstractRecipe.java:79)[12:org.apache.aries.blueprint.core:1.6.2] at java.util.concurrent.FutureTask.run(FutureTask.java:266)[:1.8.0_101] -------------------------------------------------------------------------------------------- Proposed solution -------------------------------------------------------------------------------------------- To allow route creation when database is unreachable, i've make an other "QuartzComponent" named "CustomQuartzComponent" which extends QuartzComponent and override EndPoint creation (see attached file) In fact, i've change the treatment of method "addJobInScheduler" like this private void addJobInScheduler() throws Exception { // Add or use existing trigger to/from scheduler Scheduler scheduler = getComponent().getScheduler(); JobDetail jobDetail; Trigger oldTrigger = null; //parameter added for check existing database connection boolean hasConn = true; try { oldTrigger = scheduler.getTrigger(getTriggerKey()); } catch (org.quartz.JobPersistenceException e) { // catch Exception added by me, that permit to continue // creating new CamelJob when database connection is unreachable hasConn = false; LOG.error("Customized ERROR : " + e.getMessage() + " : " + e.getCause()); } boolean triggerExisted = oldTrigger != null; if (triggerExisted && !isRecoverableJob()) { ensureNoDupTriggerKey(); } jobDetail = createJobDetail(); Trigger trigger = createTrigger(jobDetail); QuartzHelper.updateJobDataMap(getCamelContext(), jobDetail, getEndpointUri(), isUsingFixedCamelContextName()); if (triggerExisted) { // Reschedule job if trigger settings were changed if (hasTriggerChanged(oldTrigger, trigger)) { scheduler.rescheduleJob(getTriggerKey(), trigger); } // condition added by me make job scheduling only when // database connection exist } else if (hasConn) { try { // Schedule it now. Remember that scheduler might not be started // it, but we can schedule now. scheduler.scheduleJob(jobDetail, trigger); } catch (ObjectAlreadyExistsException ex) { // some other VM might may have stored the job & trigger in DB // in clustered mode, in the mean time if (!(getComponent().isClustered())) { throw ex; } else { trigger = scheduler.getTrigger(getTriggerKey()); if (trigger == null) { throw new SchedulerException("Trigger could not be found in quartz scheduler."); } } } } if (LOG.isInfoEnabled()) { LOG.info("Job {} (triggerType={}, jobClass={}) is scheduled. Next fire date is {}", new Object[] { trigger.getKey(), trigger.getClass().getSimpleName(), jobDetail.getJobClass().getSimpleName(), trigger.getNextFireTime() }); } // Increase camel job count for this endpoint AtomicInteger number = (AtomicInteger) scheduler.getContext().get(QuartzConstants.QUARTZ_CAMEL_JOBS_COUNT); if (number != null) { number.incrementAndGet(); } jobAdded.set(true); } *You confirm this proposal?* CustomQuartzComponent.java <http://camel.465427.n5.nabble.com/file/n5789552/CustomQuartzComponent.java> CustomQuartzEndpoint.java <http://camel.465427.n5.nabble.com/file/n5789552/CustomQuartzEndpoint.java> -- View this message in context: http://camel.465427.n5.nabble.com/camel-quartz-failed-camel-route-creation-when-database-is-unreachable-tp5789552.html Sent from the Camel - Users mailing list archive at Nabble.com.