/* * 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.brooklyn.core.mgmt.persist; import java.util.Date; import java.util.List; import java.util.Map; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode; import org.apache.brooklyn.core.mgmt.persist.PersistMode; import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore; import org.apache.brooklyn.core.mgmt.persist.StoreObjectAccessorLocking; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Objects; public class InMemoryObjectStore implements PersistenceObjectStore { private static final Logger log = LoggerFactory.getLogger(InMemoryObjectStore.class); final Map<String,String> filesByName; final Map<String, Date> fileModTimesByName; boolean prepared = false; public InMemoryObjectStore() { this(MutableMap.<String,String>of(), MutableMap.<String,Date>of()); } public InMemoryObjectStore(Map<String,String> map, Map<String, Date> fileModTimesByName) { filesByName = map; this.fileModTimesByName = fileModTimesByName; log.debug("Using memory-based objectStore"); } @Override public String getSummaryName() { return "in-memory (test) persistence store"; } @Override public void prepareForMasterUse() { } @Override public void createSubPath(String subPath) { } @Override public StoreObjectAccessor newAccessor(final String path) { if (!prepared) throw new IllegalStateException("prepare method not yet invoked: "+this); return new StoreObjectAccessorLocking(new SingleThreadedInMemoryStoreObjectAccessor(filesByName, fileModTimesByName, path)); } public static class SingleThreadedInMemoryStoreObjectAccessor implements StoreObjectAccessor { private final Map<String, String> map; private final Map<String, Date> mapModTime; private final String key; public SingleThreadedInMemoryStoreObjectAccessor(Map<String,String> map, Map<String, Date> mapModTime, String key) { this.map = map; this.mapModTime = mapModTime; this.key = key; } @Override public String get() { synchronized (map) { return map.get(key); } } @Override public byte[] getBytes() { return get().getBytes(); } @Override public boolean exists() { synchronized (map) { return map.containsKey(key); } } @Override public void put(String val) { synchronized (map) { map.put(key, val); mapModTime.put(key, new Date()); } } @Override public void append(String val) { synchronized (map) { String val2 = get(); if (val2==null) val2 = val; else val2 = val2 + val; map.put(key, val2); mapModTime.put(key, new Date()); } } @Override public void delete() { synchronized (map) { map.remove(key); mapModTime.remove(key); } } @Override public Date getLastModifiedDate() { synchronized (map) { return mapModTime.get(key); } } } @Override public List<String> listContentsWithSubPath(final String parentSubPath) { if (!prepared) throw new IllegalStateException("prepare method not yet invoked: "+this); synchronized (filesByName) { List<String> result = MutableList.of(); for (String file: filesByName.keySet()) if (file.startsWith(parentSubPath)) result.add(file); return result; } } @Override public void close() { } @Override public String toString() { return Objects.toStringHelper(this).add("size", filesByName.size()).toString(); } @Override public void injectManagementContext(ManagementContext mgmt) { } @Override public void prepareForSharedUse(PersistMode persistMode, HighAvailabilityMode haMode) { prepared = true; } @Override public void deleteCompletely() { synchronized (filesByName) { filesByName.clear(); } } }