diff --git a/docker/Dockerfile b/docker/Dockerfile
index f4d90028..ad2cf413 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -7,7 +7,6 @@ RUN test -n "$TARBALL"
ENV WEB_PORT=4500
EXPOSE $WEB_PORT
-ENV JAVA_HOME /usr/lib/jvm/java-11-openjdk-amd64
RUN apt-get update \
&& apt-get -y dist-upgrade \
diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml
new file mode 100644
index 00000000..af61e5b2
--- /dev/null
+++ b/docker/docker-compose.yaml
@@ -0,0 +1,48 @@
+version: '3'
+services:
+ zk:
+ image: zookeeper:3.9.2
+ hostname: zk
+ ports:
+ - "2181:2181"
+ healthcheck:
+ test: ["CMD", "curl", "-sf", "http://localhost:8080/commands/stat"]
+ interval: 5s
+ timeout: 5s
+ retries: 20
+ restart: always
+
+ bookie-1:
+ image: apache/bookkeeper:4.16.5
+ hostname: bk-1
+ ports:
+ - "3181:3181"
+ - "8080:8080"
+ environment:
+ - BK_zkServers=zk:2181
+ - BK_metadataServiceUri=zk+null://zk:2181/ledgers
+ - BK_DATA_DIR=/data/bookkeeper
+ - BK_useHostNameAsBookieID=true
+ - BK_bookiePort=3181
+ - BK_httpServerEnabled=true
+ depends_on:
+ - "zk"
+ restart: always
+
+ bookie-1-insert:
+ image: apache/bookkeeper:4.16.5
+ depends_on:
+ - bookie-1
+ restart: on-failure
+ environment:
+ - BK_zkServers=zk:2181
+ - BK_metadataServiceUri=zk+null://zk:2181/ledgers
+ entrypoint: [ "bash", "-c", "source /opt/bookkeeper/scripts/common.sh && bin/bookkeeper shell simpletest -e 1 -a 1 -w 1" ]
+
+ bkvm:
+ ports:
+ - "4500:4500"
+ image: bkvm/bkvm:latest
+ environment:
+ BKVM_metadataServiceUri: zk://zk:2181/ledgers
+
diff --git a/pom.xml b/pom.xml
index aeef1374..31e60d57 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,7 +61,7 @@
2.35
3.1.1
4.1.4
- 2.7.5
+ 2.7.14
3.1.7
2.3.1
@@ -70,7 +70,7 @@
6.1.6
1.0.2.3
33.1.0-jre
- 3.19.6
+ 3.24.0
1.6.10
6.5.0
@@ -107,7 +107,7 @@
org.eclipse.persistence
org.eclipse.persistence.asm
- ${eclipselink.version}
+ 9.7.0
org.eclipse.persistence
diff --git a/web/src/main/java/org/bkvm/auth/AuthManager.java b/web/src/main/java/org/bkvm/auth/AuthManager.java
index 2661dfa9..fd4898ad 100644
--- a/web/src/main/java/org/bkvm/auth/AuthManager.java
+++ b/web/src/main/java/org/bkvm/auth/AuthManager.java
@@ -23,7 +23,6 @@
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.apache.commons.lang3.EnumUtils;
import org.bkvm.config.ConfigurationStore;
/**
@@ -57,7 +56,7 @@ public AuthManager(ConfigurationStore store) {
}
private boolean checkUserRole(String role) {
- return EnumUtils.isValidEnum(UserRole.class, role);
+ return UserRole.Fields.isValidRole(role);
}
public boolean login(String username, String password) {
diff --git a/web/src/main/java/org/bkvm/auth/UserRole.java b/web/src/main/java/org/bkvm/auth/UserRole.java
index b9db9fb3..7dc141b0 100644
--- a/web/src/main/java/org/bkvm/auth/UserRole.java
+++ b/web/src/main/java/org/bkvm/auth/UserRole.java
@@ -19,10 +19,15 @@
*/
package org.bkvm.auth;
-import lombok.experimental.FieldNameConstants;
+import java.util.Set;
-@FieldNameConstants
-public enum UserRole {
- @FieldNameConstants.Include Admin,
- @FieldNameConstants.Include User
+public class UserRole {
+ public static class Fields {
+ public static final String Admin = "Admin";
+ public static final String User = "User";
+ private static final Set ALL = Set.of(Admin, User);
+ public static boolean isValidRole(String role) {
+ return ALL.contains(role);
+ }
+ }
}
diff --git a/web/src/main/java/org/bkvm/bookkeeper/BookkeeperClusterPool.java b/web/src/main/java/org/bkvm/bookkeeper/BookkeeperClusterPool.java
index a9f9ca2b..ba810c68 100644
--- a/web/src/main/java/org/bkvm/bookkeeper/BookkeeperClusterPool.java
+++ b/web/src/main/java/org/bkvm/bookkeeper/BookkeeperClusterPool.java
@@ -65,7 +65,7 @@ public BookkeeperCluster ensureCluster(int clusterId, String metadataServiceUri,
conf.setProperty(p, properties.get(p));
}
} catch (IOException ex) {
- LOG.log(Level.INFO, "Wrong configuration passed {0}", configuration);
+ LOG.log(Level.SEVERE, "Wrong configuration passed {0}", configuration);
}
LOG.log(Level.INFO, "Creating cluster {0}, at {1}", new Object[]{clusterId, metadataServiceUri});
diff --git a/web/src/main/java/org/bkvm/bookkeeper/BookkeeperManager.java b/web/src/main/java/org/bkvm/bookkeeper/BookkeeperManager.java
index b4911286..31b46a43 100644
--- a/web/src/main/java/org/bkvm/bookkeeper/BookkeeperManager.java
+++ b/web/src/main/java/org/bkvm/bookkeeper/BookkeeperManager.java
@@ -129,6 +129,7 @@ public enum RefreshStatus {
IDLE,
WORKING
}
+
private volatile long lastMetadataCacheRefresh;
private final ConcurrentHashMap lastClusterWideConfiguration = new ConcurrentHashMap<>();
private final AtomicReference refreshStatus = new AtomicReference<>(RefreshStatus.IDLE);
@@ -167,7 +168,7 @@ public static final class RefreshCacheWorkerStatus {
private final Map lastClusterWideConfiguration;
public RefreshCacheWorkerStatus(RefreshStatus status, long lastMetadataCacheRefresh,
- Map lastClusterWideConfiguration) {
+ Map lastClusterWideConfiguration) {
this.status = status;
this.lastMetadataCacheRefresh = lastMetadataCacheRefresh;
this.lastClusterWideConfiguration = lastClusterWideConfiguration;
@@ -281,15 +282,15 @@ public void doRefreshMetadataCache() {
metadataCache.deleteBookie(b.getClusterId(), b.getBookieId());
}
}
+ Set deletedLedgers = new HashSet<>(metadataCache.listLedgers(clusterId));
Iterable ledgersIds = bkAdmin.listLedgers();
for (long ledgerId : ledgersIds) {
LedgerMetadata ledgerMetadata = readLedgerMetadata(ledgerId, clusterId);
if (ledgerMetadata == null) {
- // ledger disappeared
- metadataCache.deleteLedger(clusterId, ledgerId);
- return;
+ continue;
}
+ deletedLedgers.remove(ledgerId);
Ledger ledger = new Ledger(ledgerId, clusterId,
ledgerMetadata.getLength(),
new java.sql.Timestamp(ledgerMetadata.getCtime()),
@@ -308,6 +309,10 @@ public void doRefreshMetadataCache() {
LOG.log(Level.FINE, "Updating ledger {0} metadata", ledgerId);
metadataCache.updateLedger(ledger, bookies, metadataEntries);
}
+ for (Long deletedLedger : deletedLedgers) {
+ metadataCache.deleteLedger(clusterId, deletedLedger);
+ }
+
}
topologyCache.refreshBookiesTopology();
@@ -528,7 +533,8 @@ private static ClusterWideConfiguration getClusterWideConfiguration(int clusterI
autoRecoveryEnabled = underreplicationManager.isLedgerReplicationEnabled();
lostBookieRecoveryDelay = underreplicationManager.getLostBookieRecoveryDelay();
}
- } catch (ReplicationException.UnavailableException | ReplicationException.CompatibilityException notConfigured) {
+ } catch (ReplicationException.UnavailableException
+ | ReplicationException.CompatibilityException notConfigured) {
// auto replication stuff never initialized
LOG.log(Level.INFO, "Cannot get auditor info: {0}", notConfigured + ""); // do not write stacktrace
}
@@ -542,7 +548,7 @@ private static ClusterWideConfiguration getClusterWideConfiguration(int clusterI
autoRecoveryEnabled, lostBookieRecoveryDelay,
layoutFormatVersion, layoutManagerFactoryClass, layoutManagerVersion);
} catch (InterruptedException
- | MetadataException | IOException ex) {
+ | MetadataException | IOException ex) {
LOG.log(Level.SEVERE, "Error", ex);
throw new BookkeeperManagerException(ex);
} finally {
diff --git a/web/src/main/java/org/bkvm/cache/MetadataCache.java b/web/src/main/java/org/bkvm/cache/MetadataCache.java
index 2026d99b..0479a58b 100644
--- a/web/src/main/java/org/bkvm/cache/MetadataCache.java
+++ b/web/src/main/java/org/bkvm/cache/MetadataCache.java
@@ -207,13 +207,21 @@ public List listLedgers() {
}
}
+ public List listLedgers(int clusterId) {
+ try (EntityManagerWrapper emw = getEntityManager()) {
+ EntityManager em = emw.em;
+ Query q = em.createQuery("select l.ledgerId from ledger l where l.clusterId=" + clusterId, Ledger.class);
+ return q.getResultList();
+ }
+ }
+
public void updateLedger(Ledger ledger, List bookies,
List metadataEntries) {
try (EntityManagerWrapper emw = getEntityManager()) {
EntityManager em = emw.em;
em.getTransaction().begin();
long ledgerId = ledger.getLedgerId();
- innerDeleteLedger(ledger.getClusterId(), ledger.getLedgerId(), em);
+ innerDeleteLedger(ledger.getClusterId(), ledgerId, em);
em.persist(ledger);
bookies.forEach((lb) -> {
if (ledgerId != lb.getLedgerId()) {
@@ -243,7 +251,7 @@ public void deleteLedger(int clusterId, long ledgerId) {
}
}
- private void innerDeleteLedger(int clusterId, long ledgerId, EntityManager em) {
+ private static void innerDeleteLedger(int clusterId, long ledgerId, EntityManager em) {
em.createQuery("DELETE FROM ledger_metadata lm where lm.ledgerId=" + ledgerId + " and lm.clusterId=" + clusterId).executeUpdate();
em.createQuery("DELETE FROM ledger_bookie lm where lm.ledgerId=" + ledgerId + " and lm.clusterId=" + clusterId).executeUpdate();
em.createQuery("DELETE FROM ledger lm where lm.ledgerId=" + ledgerId + " and lm.clusterId=" + clusterId).executeUpdate();
diff --git a/web/src/test/java/org/bkvm/cache/LoadMetadataCacheTest.java b/web/src/test/java/org/bkvm/cache/LoadMetadataCacheTest.java
new file mode 100644
index 00000000..839852f0
--- /dev/null
+++ b/web/src/test/java/org/bkvm/cache/LoadMetadataCacheTest.java
@@ -0,0 +1,67 @@
+/*
+ Licensed to Diennea S.r.l. under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. Diennea S.r.l. 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.bkvm.cache;
+
+import static org.junit.Assert.assertEquals;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import org.apache.bookkeeper.client.BookKeeper;
+import org.apache.bookkeeper.client.api.WriteHandle;
+import org.apache.bookkeeper.conf.ClientConfiguration;
+import org.bkvm.bookkeeper.BookkeeperManager;
+import org.bkvm.utils.BookkeeperManagerTestUtils;
+import org.junit.Test;
+
+
+public class LoadMetadataCacheTest extends BookkeeperManagerTestUtils {
+
+ @Test
+ public void testLoad() throws Exception {
+ startBookie(false, -1);
+ ClientConfiguration bkConf = new ClientConfiguration();
+ bkConf.setMetadataServiceUri(getMetadataServiceUri());
+
+ BookKeeper bk = BookKeeper.forConfig(bkConf).build();
+ WriteHandle wr0 = createLedger(bk);
+ WriteHandle wr = createLedger(bk);
+ wr.append("test".getBytes());
+ final BookkeeperManager bookkeeperManager = getBookkeeperManager();
+ bookkeeperManager.doRefreshMetadataCache();
+ assertEquals(2, bookkeeperManager.getAllLedgers().size());
+
+ bk.newDeleteLedgerOp()
+ .withLedgerId(wr.getId())
+ .execute().get();
+ bookkeeperManager.doRefreshMetadataCache();
+ assertEquals(1, bookkeeperManager.getAllLedgers().size());
+ }
+
+ private static WriteHandle createLedger(BookKeeper bk) throws InterruptedException, ExecutionException {
+ WriteHandle wr = bk.newCreateLedgerOp()
+ .withAckQuorumSize(1)
+ .withEnsembleSize(1)
+ .withWriteQuorumSize(1)
+ .withPassword("p".getBytes())
+ .withCustomMetadata(Map.of("meta1", "value1".getBytes()))
+ .execute().get();
+ return wr;
+ }
+
+}
\ No newline at end of file
diff --git a/web/src/test/java/org/bkvm/utils/BookkeeperManagerTestUtils.java b/web/src/test/java/org/bkvm/utils/BookkeeperManagerTestUtils.java
index 59e06560..37a17f35 100644
--- a/web/src/test/java/org/bkvm/utils/BookkeeperManagerTestUtils.java
+++ b/web/src/test/java/org/bkvm/utils/BookkeeperManagerTestUtils.java
@@ -27,7 +27,6 @@
import org.bkvm.cache.MetadataCache;
import org.bkvm.config.ConfigurationStore;
import org.bkvm.config.PropertiesConfigurationStore;
-import org.bkvm.config.ServerConfiguration;
import org.junit.After;
import org.junit.Before;
@@ -55,17 +54,17 @@ public void beforeSetup() throws Exception {
datasource = new HerdDBEmbeddedDataSource();
datasource.setUrl("jdbc:herddb:local");
metadataCache = new MetadataCache(datasource);
- final Properties properties = new Properties();
- properties.put(ServerConfiguration.PROPERTY_BOOKKEEPER_METADATA_SERVICE_URI,
- "zk+null://" + getZooKeeperAddress() + "/ledgers");
-
ConfigurationStore config = new PropertiesConfigurationStore(new Properties());
bookkeeperManager = new BookkeeperManager(config, metadataCache);
init();
}
protected void init() throws Exception {
- createCluster("cluster1", "zk+null://" + getZooKeeperAddress() + "/ledgers", "");
+ createCluster("cluster1", getMetadataServiceUri(), "");
+ }
+
+ protected String getMetadataServiceUri() {
+ return "zk+null://" + getZooKeeperAddress() + "/ledgers";
}
protected Cluster createCluster(String name, String metadataServiceUri, String configuration) throws BookkeeperManagerException {