Repository: camel
Updated Branches:
  refs/heads/master 1611a1930 -> 300c1277f


CAMEL-11841: cluster service : make a simple FileLock based service


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/300c1277
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/300c1277
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/300c1277

Branch: refs/heads/master
Commit: 300c1277f8418ee57ec7d894b93077968ef69add
Parents: 1611a19
Author: lburgazzoli <lburgazz...@gmail.com>
Authored: Tue Sep 26 12:43:55 2017 +0200
Committer: lburgazzoli <lburgazz...@gmail.com>
Committed: Tue Sep 26 14:06:16 2017 +0200

----------------------------------------------------------------------
 .../file/ha/FileLockClusterService.java         | 138 ++++++++++++++
 .../component/file/ha/FileLockClusterView.java  | 181 +++++++++++++++++++
 .../ha/FileLockClusteredRoutePolicyTest.java    | 108 +++++++++++
 camel-core/src/test/resources/log4j2.properties |   5 +-
 ...FileLockClusterServiceAutoConfiguration.java |  65 +++++++
 .../ha/FileLockClusterServiceConfiguration.java |  87 +++++++++
 .../main/resources/META-INF/spring.factories    |   1 +
 7 files changed, 584 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/300c1277/camel-core/src/main/java/org/apache/camel/component/file/ha/FileLockClusterService.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/component/file/ha/FileLockClusterService.java
 
b/camel-core/src/main/java/org/apache/camel/component/file/ha/FileLockClusterService.java
new file mode 100644
index 0000000..2d207de
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/component/file/ha/FileLockClusterService.java
@@ -0,0 +1,138 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.ha;
+
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.ha.AbstractCamelClusterService;
+import org.apache.camel.util.ObjectHelper;
+
+public class FileLockClusterService extends 
AbstractCamelClusterService<FileLockClusterView> {
+    private String root;
+    private long acquireLockDelay;
+    private TimeUnit acquireLockDelayUnit;
+    private long acquireLockInterval;
+    private TimeUnit acquireLockIntervalUnit;
+    private ScheduledExecutorService executor;
+
+    public FileLockClusterService() {
+        this.acquireLockDelay = 1;
+        this.acquireLockDelayUnit = TimeUnit.SECONDS;
+        this.acquireLockInterval = 10;
+        this.acquireLockIntervalUnit = TimeUnit.SECONDS;
+    }
+
+    @Override
+    protected FileLockClusterView createView(String namespace) throws 
Exception {
+        return new FileLockClusterView(this, namespace);
+    }
+
+    public String getRoot() {
+        return root;
+    }
+
+    /**
+     * Sets the root path.
+     */
+    public void setRoot(String root) {
+        this.root = root;
+    }
+
+    public long getAcquireLockDelay() {
+        return acquireLockDelay;
+    }
+
+    /**
+     * The time to wait before starting to try to acquire lock, default 1.
+     */
+    public void setAcquireLockDelay(long acquireLockDelay) {
+        this.acquireLockDelay = acquireLockDelay;
+    }
+
+    public void setAcquireLockDelay(long pollDelay, TimeUnit pollDelayUnit) {
+        setAcquireLockDelay(pollDelay);
+        setAcquireLockDelayUnit(pollDelayUnit);
+    }
+
+    public TimeUnit getAcquireLockDelayUnit() {
+        return acquireLockDelayUnit;
+    }
+
+    /**
+     * The time unit fo the acquireLockDelay, default to TimeUnit.SECONDS.
+     */
+    public void setAcquireLockDelayUnit(TimeUnit acquireLockDelayUnit) {
+        this.acquireLockDelayUnit = acquireLockDelayUnit;
+    }
+
+    public long getAcquireLockInterval() {
+        return acquireLockInterval;
+    }
+
+    /**
+     * The time to wait between attempts to try to acquire lock, default 10.
+     */
+    public void setAcquireLockInterval(long acquireLockInterval) {
+        this.acquireLockInterval = acquireLockInterval;
+    }
+
+    public void setAcquireLockInterval(long pollInterval, TimeUnit 
pollIntervalUnit) {
+        setAcquireLockInterval(pollInterval);
+        setAcquireLockIntervalUnit(pollIntervalUnit);
+    }
+
+    public TimeUnit getAcquireLockIntervalUnit() {
+        return acquireLockIntervalUnit;
+    }
+
+    /**
+     * The time unit fo the acquireLockInterva, default to TimeUnit.SECONDS.
+     */
+    public void setAcquireLockIntervalUnit(TimeUnit acquireLockIntervalUnit) {
+        this.acquireLockIntervalUnit = acquireLockIntervalUnit;
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+
+        CamelContext context = getCamelContext();
+
+        if (executor != null) {
+            if (context != null) {
+                context.getExecutorServiceManager().shutdown(executor);
+            } else {
+                executor.shutdown();
+            }
+
+            executor = null;
+        }
+    }
+
+    synchronized ScheduledExecutorService getExecutor() {
+        if (executor == null) {
+            // Camel context should be set at this stage.
+            final CamelContext context = 
ObjectHelper.notNull(getCamelContext(), "CamelContext");
+
+            executor = 
context.getExecutorServiceManager().newSingleThreadScheduledExecutor(this, 
"FileLockClusterService-" + getId());
+        }
+
+        return executor;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/300c1277/camel-core/src/main/java/org/apache/camel/component/file/ha/FileLockClusterView.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/component/file/ha/FileLockClusterView.java
 
b/camel-core/src/main/java/org/apache/camel/component/file/ha/FileLockClusterView.java
new file mode 100644
index 0000000..6fcf703
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/component/file/ha/FileLockClusterView.java
@@ -0,0 +1,181 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.ha;
+
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.OverlappingFileLockException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.ha.CamelClusterMember;
+import org.apache.camel.impl.ha.AbstractCamelClusterView;
+import org.apache.camel.util.IOHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FileLockClusterView extends AbstractCamelClusterView {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(FileLockClusterView.class);
+
+    private final ClusterMember localMember;
+    private final Path path;
+    private RandomAccessFile file;
+    private FileChannel channel;
+    private FileLock lock;
+    private ScheduledFuture<?> task;
+
+    FileLockClusterView(FileLockClusterService cluster, String namespace) {
+        super(cluster, namespace);
+
+        this.localMember = new ClusterMember();
+        this.path = Paths.get(cluster.getRoot(), namespace);
+
+    }
+
+    @Override
+    public Optional<CamelClusterMember> getMaster() {
+        return Optional.of(this.localMember);
+    }
+
+    @Override
+    public CamelClusterMember getLocalMember() {
+        return this.localMember;
+    }
+
+    @Override
+    public List<CamelClusterMember> getMembers() {
+        // It may be useful to lock only a region of the file an then have 
views
+        // appending their id to the file on different regions so we can
+        // have a list of members. Root/Header region that is used for locking
+        // purpose may also contains the lock holder.
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        if (file != null) {
+            close();
+
+            fireLeadershipChangedEvent(Optional.empty());
+        }
+
+        if (!Files.exists(path.getParent())) {
+            Files.createDirectories(path.getParent());
+        }
+
+        file = new RandomAccessFile(path.toFile(), "rw");
+        channel = file.getChannel();
+
+        FileLockClusterService service = 
getClusterService().unwrap(FileLockClusterService.class);
+        ScheduledExecutorService executor = service.getExecutor();
+
+        task = executor.scheduleAtFixedRate(
+            this::tryLock,
+            TimeUnit.MILLISECONDS.convert(service.getAcquireLockDelay(), 
service.getAcquireLockDelayUnit()),
+            TimeUnit.MILLISECONDS.convert(service.getAcquireLockInterval(), 
service.getAcquireLockIntervalUnit()),
+            TimeUnit.MILLISECONDS
+        );
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        close();
+    }
+
+    // *********************************
+    //
+    // *********************************
+
+    private void close() throws Exception {
+        if (task != null) {
+            task.cancel(true);
+        }
+
+        if (lock != null) {
+            lock.release();
+        }
+
+        if (file != null) {
+            IOHelper.close(channel);
+            IOHelper.close(file);
+
+            channel = null;
+            file = null;
+        }
+    }
+
+    private void tryLock() {
+        if (isStarting() || isStarted()) {
+            try {
+                if (localMember.isLeader()) {
+                    LOGGER.trace("Holding the lock on file {} (lock={})", 
path, lock);
+                    return;
+                }
+
+                synchronized (FileLockClusterView.this) {
+                    if (lock != null) {
+                        LOGGER.info("Lock on file {} lost (lock={})", path, 
lock);
+                        fireLeadershipChangedEvent(Optional.empty());
+                    }
+
+                    LOGGER.debug("Try to acquire a lock on {}", path);
+
+                    lock = null;
+                    lock = channel.tryLock();
+
+                    if (lock != null) {
+                        LOGGER.info("Lock on file {} acquired (lock={})", 
path, lock);
+                        fireLeadershipChangedEvent(Optional.of(localMember));
+                    } else {
+                        LOGGER.debug("Lock on file {} not acquired ", path);
+                    }
+                }
+            } catch (OverlappingFileLockException e) {
+                LOGGER.debug("Lock on file {} not acquired ", path);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private final class ClusterMember implements CamelClusterMember {
+        @Override
+        public boolean isLeader() {
+            synchronized (FileLockClusterView.this) {
+                return lock != null && lock.isValid();
+            }
+        }
+
+        @Override
+        public boolean isLocal() {
+            return true;
+        }
+
+        @Override
+        public String getId() {
+            return getClusterService().getId();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/300c1277/camel-core/src/test/java/org/apache/camel/component/file/ha/FileLockClusteredRoutePolicyTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/component/file/ha/FileLockClusteredRoutePolicyTest.java
 
b/camel-core/src/test/java/org/apache/camel/component/file/ha/FileLockClusteredRoutePolicyTest.java
new file mode 100644
index 0000000..3e19566
--- /dev/null
+++ 
b/camel-core/src/test/java/org/apache/camel/component/file/ha/FileLockClusteredRoutePolicyTest.java
@@ -0,0 +1,108 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.ha;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.ha.ClusteredRoutePolicyFactory;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class FileLockClusteredRoutePolicyTest {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(FileLockClusteredRoutePolicyTest.class);
+    private static final List<String> CLIENTS = IntStream.range(0, 
3).mapToObj(Integer::toString).collect(Collectors.toList());
+    private static final List<String> RESULTS = new ArrayList<>();
+    private static final ScheduledExecutorService SCHEDULER = 
Executors.newScheduledThreadPool(CLIENTS.size());
+    private static final CountDownLatch LATCH = new 
CountDownLatch(CLIENTS.size());
+
+    // ************************************
+    // Test
+    // ************************************
+
+    @Test
+    public void test() throws Exception {
+        for (String id : CLIENTS) {
+            SCHEDULER.submit(() -> run(id));
+        }
+
+        LATCH.await(1, TimeUnit.MINUTES);
+        SCHEDULER.shutdownNow();
+
+        Assert.assertEquals(CLIENTS.size(), RESULTS.size());
+        Assert.assertTrue(RESULTS.containsAll(CLIENTS));
+    }
+
+    // ************************************
+    // Run a Camel node
+    // ************************************
+
+    private static void run(String id) {
+        try {
+            int events = ThreadLocalRandom.current().nextInt(2, 6);
+            CountDownLatch contextLatch = new CountDownLatch(events);
+
+            FileLockClusterService service = new FileLockClusterService();
+            service.setId("node-" + id);
+            service.setRoot("target/ha");
+            service.setAcquireLockDelay(1, TimeUnit.SECONDS);
+            service.setAcquireLockInterval(1, TimeUnit.SECONDS);
+
+            DefaultCamelContext context = new DefaultCamelContext();
+            context.disableJMX();
+            context.setName("context-" + id);
+            context.addService(service);
+            
context.addRoutePolicyFactory(ClusteredRoutePolicyFactory.forNamespace("my-ns"));
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() throws Exception {
+                    from("timer:file-lock?delay=1s&period=1s")
+                        .routeId("route-" + id)
+                        .log("From ${routeId}")
+                        .process(e -> contextLatch.countDown());
+                }
+            });
+
+            // Start the context after some random time so the startup order
+            // changes for each test.
+            Thread.sleep(ThreadLocalRandom.current().nextInt(500));
+            context.start();
+
+            contextLatch.await();
+
+            LOGGER.debug("Shutting down node {}", id);
+            RESULTS.add(id);
+
+            context.stop();
+
+            LATCH.countDown();
+        } catch (Exception e) {
+            LOGGER.warn("", e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/300c1277/camel-core/src/test/resources/log4j2.properties
----------------------------------------------------------------------
diff --git a/camel-core/src/test/resources/log4j2.properties 
b/camel-core/src/test/resources/log4j2.properties
index 98bc5d1..85f3188 100644
--- a/camel-core/src/test/resources/log4j2.properties
+++ b/camel-core/src/test/resources/log4j2.properties
@@ -37,10 +37,13 @@ logger.customlogger.name = org.apache.camel.customlogger
 logger.customlogger.level = TRACE
 logger.customlogger.appenderRef.file2.ref = file2
 
+logger.file-ha.name = org.apache.camel.component.file.ha
+logger.file-ha.level = DEBUG
+
 rootLogger.level = INFO
 
 rootLogger.appenderRef.file.ref = file
-#rootLogger.appenderRef.file.ref = console
+#rootLogger.appenderRef.console.ref = console
 
 #logger.camel-core.name = org.apache.camel.impl
 #logger.camel-core.level = DEBUG

http://git-wip-us.apache.org/repos/asf/camel/blob/300c1277/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/component/file/springboot/ha/FileLockClusterServiceAutoConfiguration.java
----------------------------------------------------------------------
diff --git 
a/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/component/file/springboot/ha/FileLockClusterServiceAutoConfiguration.java
 
b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/component/file/springboot/ha/FileLockClusterServiceAutoConfiguration.java
new file mode 100644
index 0000000..689127e
--- /dev/null
+++ 
b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/component/file/springboot/ha/FileLockClusterServiceAutoConfiguration.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.springboot.ha;
+
+
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.component.file.ha.FileLockClusterService;
+import org.apache.camel.converter.TimePatternConverter;
+import org.apache.camel.ha.CamelClusterService;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import 
org.apache.camel.spring.boot.ha.ClusteredRouteControllerAutoConfiguration;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import 
org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+
+@Configuration
+@AutoConfigureBefore({ ClusteredRouteControllerAutoConfiguration.class, 
CamelAutoConfiguration.class })
+@ConditionalOnProperty(prefix = "camel.component.file.cluster.service", name = 
"enabled")
+@EnableConfigurationProperties(FileLockClusterServiceConfiguration.class)
+public class FileLockClusterServiceAutoConfiguration {
+    @Autowired
+    private FileLockClusterServiceConfiguration configuration;
+
+    @Bean(initMethod = "start", destroyMethod = "stop")
+    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
+    @ConditionalOnMissingBean
+    public CamelClusterService consulClusterService() throws Exception {
+        FileLockClusterService service = new FileLockClusterService();
+
+        Optional.ofNullable(configuration.getId())
+            .ifPresent(service::setId);
+        Optional.ofNullable(configuration.getRoot())
+            .ifPresent(service::setRoot);
+        Optional.ofNullable(configuration.getAcquireLockDelay())
+            .map(TimePatternConverter::toMilliSeconds)
+            .ifPresent(v -> service.setAcquireLockDelay(v, 
TimeUnit.MILLISECONDS));
+        Optional.ofNullable(configuration.getAcquireLockInterval())
+            .map(TimePatternConverter::toMilliSeconds)
+            .ifPresent(v -> service.setAcquireLockInterval(v, 
TimeUnit.MILLISECONDS));
+
+        return service;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/300c1277/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/component/file/springboot/ha/FileLockClusterServiceConfiguration.java
----------------------------------------------------------------------
diff --git 
a/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/component/file/springboot/ha/FileLockClusterServiceConfiguration.java
 
b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/component/file/springboot/ha/FileLockClusterServiceConfiguration.java
new file mode 100644
index 0000000..3ef175e
--- /dev/null
+++ 
b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/component/file/springboot/ha/FileLockClusterServiceConfiguration.java
@@ -0,0 +1,87 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.springboot.ha;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "camel.component.file.cluster.service")
+public class FileLockClusterServiceConfiguration {
+    /**
+     * Sets if the zookeeper cluster service should be enabled or not, default 
is false.
+     */
+    private boolean enabled;
+
+    /**
+     * Cluster Service ID
+     */
+    private String id;
+
+    /**
+     * The root path.
+     */
+    private String root;
+
+    /**
+     * The time to wait before starting to try to acquire lock.
+     */
+    private String acquireLockDelay;
+
+    /**
+     * The time to wait between attempts to try to acquire lock.
+     */
+    private String acquireLockInterval;
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getRoot() {
+        return root;
+    }
+
+    public void setRoot(String root) {
+        this.root = root;
+    }
+
+    public String getAcquireLockDelay() {
+        return acquireLockDelay;
+    }
+
+    public void setAcquireLockDelay(String acquireLockDelay) {
+        this.acquireLockDelay = acquireLockDelay;
+    }
+
+    public String getAcquireLockInterval() {
+        return acquireLockInterval;
+    }
+
+    public void setAcquireLockInterval(String acquireLockInterval) {
+        this.acquireLockInterval = acquireLockInterval;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/300c1277/platforms/spring-boot/components-starter/camel-core-starter/src/main/resources/META-INF/spring.factories
----------------------------------------------------------------------
diff --git 
a/platforms/spring-boot/components-starter/camel-core-starter/src/main/resources/META-INF/spring.factories
 
b/platforms/spring-boot/components-starter/camel-core-starter/src/main/resources/META-INF/spring.factories
index 253b608..800582d 100644
--- 
a/platforms/spring-boot/components-starter/camel-core-starter/src/main/resources/META-INF/spring.factories
+++ 
b/platforms/spring-boot/components-starter/camel-core-starter/src/main/resources/META-INF/spring.factories
@@ -46,6 +46,7 @@ 
org.apache.camel.component.mock.springboot.MockComponentAutoConfiguration,\
 org.apache.camel.component.browse.springboot.BrowseComponentAutoConfiguration,\
 
org.apache.camel.component.language.springboot.LanguageComponentAutoConfiguration,\
 org.apache.camel.component.file.springboot.FileComponentAutoConfiguration,\
+org.apache.camel.component.file.springboot.ha.FileLockClusterServiceAutoConfiguration,\
 org.apache.camel.component.timer.springboot.TimerComponentAutoConfiguration,\
 org.apache.camel.component.test.springboot.TestComponentAutoConfiguration,\
 
org.apache.camel.component.beanclass.springboot.ClassComponentAutoConfiguration,\

Reply via email to