/* * Copyright 2016 higherfrequencytrading.com * * Licensed 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 net.openhft.chronicle.engine.tree; import net.openhft.chronicle.core.Jvm; import net.openhft.chronicle.core.io.Closeable; import net.openhft.chronicle.core.threads.EventLoop; import net.openhft.chronicle.engine.api.column.ColumnViewInternal.SortedFilter; import net.openhft.chronicle.engine.api.column.ColumnViewIterator; import net.openhft.chronicle.engine.api.tree.Asset; import net.openhft.chronicle.engine.api.tree.AssetTree; import net.openhft.chronicle.engine.api.tree.AssetTreeStats; import net.openhft.chronicle.engine.fs.ConfigurationFS; import net.openhft.chronicle.engine.map.InsertedEvent; import net.openhft.chronicle.engine.map.RemovedEvent; import net.openhft.chronicle.engine.map.UpdatedEvent; import net.openhft.chronicle.engine.map.remote.*; import net.openhft.chronicle.network.VanillaSessionDetails; import net.openhft.chronicle.network.connection.ClientConnectionMonitor; import net.openhft.chronicle.network.connection.FatalFailureConnectionStrategy; import net.openhft.chronicle.threads.Threads; import net.openhft.chronicle.wire.WireType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Optional; import java.util.function.Consumer; import static net.openhft.chronicle.core.pool.ClassAliasPool.CLASS_ALIASES; /** * Created by peter on 22/05/15. */ public class VanillaAssetTree implements AssetTree { static { CLASS_ALIASES.addAlias(AddedAssetEvent.class, ExistingAssetEvent.class, RemovedAssetEvent.class, InsertedEvent.class, UpdatedEvent.class, MapFunction.class, MapUpdate.class, RemovedEvent.class, KeyFunctionPair.class, KeyValueFunctionTuple.class, KeyValuesTuple.class, KeyValuePair.class, SortedFilter.class, ColumnViewIterator.class); } @NotNull final VanillaAsset root; public VanillaAssetTree() { this(""); } public VanillaAssetTree(@Nullable String name) { root = new VanillaAsset(null, name == null ? "" : name); } public VanillaAssetTree(int hostId) { this(); root.addView(HostIdentifier.class, new HostIdentifier((byte) hostId)); } @NotNull @Override public AssetTreeStats getUsageStats() { @NotNull AssetTreeStats ats = new AssetTreeStats(); root.getUsageStats(ats); return ats; } @NotNull public VanillaAssetTree forTesting() { return forTesting(true); } @NotNull public VanillaAssetTree forTesting(boolean daemon) { return forServer(daemon); } @NotNull public VanillaAssetTree forTesting(boolean daemon, boolean binding) { return forServer(daemon, binding); } @NotNull public VanillaAssetTree forServer() { return forServer(true); } @NotNull public VanillaAssetTree forServer(boolean daemon, boolean binding) { @Nullable final HostIdentifier view = root.getView(HostIdentifier.class); final int hostId = view == null ? 1 : view.hostId(); root.forServer(daemon, (String uri) -> VanillaAsset.master(uri, hostId), binding); return this; } @NotNull public VanillaAssetTree forServer(boolean daemon) { return forServer(daemon, false); } @NotNull public VanillaAssetTree forRemoteAccess(String hostPortDescription, @NotNull WireType wire) { return forRemoteAccess(new String[]{hostPortDescription}, wire); } @NotNull public VanillaAssetTree forRemoteAccess(@NotNull String[] hostPortDescription, @NotNull WireType wire) { root.forRemoteAccess(hostPortDescription, wire, clientSession(), null, new FatalFailureConnectionStrategy(3)); return this; } /** * creates an asset tree that connects to a remote server via tcp/ip * * @param hostPortDescription the primary host and other failover hosts * @param wire the type of wire * @param clientConnectionMonitor used to monitor client failover * @return an instance of VanillaAssetTree */ @NotNull public VanillaAssetTree forRemoteAccess(@NotNull String[] hostPortDescription, @NotNull WireType wire, @Nullable ClientConnectionMonitor clientConnectionMonitor) { if (clientConnectionMonitor != null) root.viewMap.put(ClientConnectionMonitor.class, clientConnectionMonitor); root.forRemoteAccess(hostPortDescription, wire, clientSession(), clientConnectionMonitor, new FatalFailureConnectionStrategy(3)); return this; } @NotNull public VanillaAssetTree forRemoteAccess(String hostPortDescription) { return forRemoteAccess(hostPortDescription, WireType.BINARY); } @NotNull private VanillaSessionDetails clientSession() { @NotNull final VanillaSessionDetails sessionDetails = new VanillaSessionDetails(); sessionDetails.userId(System.getProperty("user.name")); return sessionDetails; } @NotNull @Override public Asset acquireAsset(@NotNull String fullName) { if (fullName.startsWith("/")) fullName = fullName.substring(1); return fullName.isEmpty() ? root : root.acquireAsset(fullName); } @Nullable @Override public Asset getAsset(@NotNull String fullName) { if (fullName.startsWith("/")) fullName = fullName.substring(1); return fullName.isEmpty() ? root : root.getAsset(fullName); } @NotNull @Override public VanillaAsset root() { return root; } @Override public void close() { root.notifyClosing(); Jvm.pause(50); // ensure that the event loop get shutdown first @Nullable EventLoop view = root().findView(EventLoop.class); Closeable.closeQuietly(view); root.close(); } @NotNull @Deprecated public AssetTree withConfig(String etcDir, String baseDir) { Threads.withThreadGroup(root.getView(ThreadGroup.class), () -> { new ConfigurationFS("/etc", etcDir, baseDir).install(baseDir, this); return null; }); return this; } @NotNull @Override public String toString() { return "tree-" + Optional.ofNullable(root.getView(HostIdentifier.class)).map(HostIdentifier::hostId).orElseGet(() -> (byte) 0); } @NotNull public VanillaAssetTree forRemoteAccess(String serverAddress, @NotNull WireType wireType, Consumer<Throwable> t) { return forRemoteAccess(serverAddress, wireType); } }