/* * 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.ignite.internal.processors.hadoop.impl.igfs; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.configuration.FileSystemConfiguration; import org.apache.ignite.hadoop.fs.v1.IgniteHadoopFileSystem; import org.apache.ignite.igfs.IgfsIpcEndpointConfiguration; import org.apache.ignite.igfs.IgfsMode; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.testframework.GridTestUtils; /** * IGFS Hadoop file system Ignite client -based self test. */ public abstract class IgniteHadoopFileSystemClientBasedAbstractSelfTest extends IgniteHadoopFileSystemAbstractSelfTest { /** Alive node index. */ private static final int ALIVE_NODE_IDX = GRID_COUNT - 1; /** * Constructor. * * @param mode IGFS mode. */ IgniteHadoopFileSystemClientBasedAbstractSelfTest(IgfsMode mode) { super(mode, true, true); } /** {@inheritDoc} */ @Override protected IgfsIpcEndpointConfiguration primaryIpcEndpointConfiguration(final String gridName) { return null; } /** {@inheritDoc} */ @Override protected FileSystemConfiguration igfsConfiguration(String gridName) throws IgniteCheckedException { FileSystemConfiguration cfg = super.igfsConfiguration(gridName); cfg.setIpcEndpointEnabled(false); return cfg; } /** * @return Path to Ignite client node configuration. */ protected abstract String getClientConfig(); /** {@inheritDoc} */ @Override protected Configuration configuration(String authority, boolean skipEmbed, boolean skipLocShmem) { Configuration cfg = new Configuration(); cfg.set("fs.defaultFS", "igfs://" + authority + "/"); cfg.set("fs.igfs.impl", IgniteHadoopFileSystem.class.getName()); cfg.set("fs.AbstractFileSystem.igfs.impl", org.apache.ignite.hadoop.fs.v2.IgniteHadoopFileSystem.class.getName()); cfg.setBoolean("fs.igfs.impl.disable.cache", true); cfg.setBoolean(String.format(HadoopIgfsUtils.PARAM_IGFS_ENDPOINT_NO_EMBED, authority), true); cfg.setBoolean(String.format(HadoopIgfsUtils.PARAM_IGFS_ENDPOINT_NO_LOCAL_SHMEM, authority), true); cfg.setBoolean(String.format(HadoopIgfsUtils.PARAM_IGFS_ENDPOINT_NO_LOCAL_TCP, authority), true); cfg.setBoolean(String.format(HadoopIgfsUtils.PARAM_IGFS_ENDPOINT_NO_REMOTE_TCP, authority), true); cfg.setStrings(String.format(HadoopIgfsUtils.PARAM_IGFS_ENDPOINT_IGNITE_CFG_PATH, authority), getClientConfig()); return cfg; } /** {@inheritDoc} */ @Override public void testClientReconnect() throws Exception { Path filePath = new Path(PRIMARY_URI, "file1"); final FSDataOutputStream s = fs.create(filePath); // Open the stream before stopping IGFS. try { restartServerNodesExceptOne(); // Check that client is again operational. assertTrue(fs.mkdirs(new Path(PRIMARY_URI, "dir1/dir2"))); s.write("test".getBytes()); s.flush(); // Flush data to the broken output stream. assertTrue(fs.exists(filePath)); } finally { U.closeQuiet(s); // Safety. } } /** * Verifies that client reconnects after connection to the server has been lost (multithreaded mode). * * @throws Exception If error occurs. */ @Override public void testClientReconnectMultithreaded() throws Exception { final ConcurrentLinkedQueue<FileSystem> q = new ConcurrentLinkedQueue<>(); Configuration cfg = new Configuration(); for (Map.Entry<String, String> entry : primaryFsCfg) cfg.set(entry.getKey(), entry.getValue()); cfg.setBoolean("fs.igfs.impl.disable.cache", true); final int nClients = 1; // Initialize clients. for (int i = 0; i < nClients; i++) q.add(FileSystem.get(primaryFsUri, cfg)); restartServerNodesExceptOne(); GridTestUtils.runMultiThreaded(new Callable<Object>() { @Override public Object call() throws Exception { FileSystem fs = q.poll(); try { // Check that client is again operational. assertTrue(fs.mkdirs(new Path("/" + Thread.currentThread().getName()))); return true; } finally { U.closeQuiet(fs); } } }, nClients, "test-client"); } /** * * @throws Exception If failed. */ private void restartServerNodesExceptOne() throws Exception { stopAllNodesExcept(ALIVE_NODE_IDX); Thread.sleep(500); startAllNodesExcept(ALIVE_NODE_IDX); // Start server again. Thread.sleep(500); stopGrid(ALIVE_NODE_IDX); Thread.sleep(500); startGrid(ALIVE_NODE_IDX); Thread.sleep(500); } /** * @param nodeIdx Node index to not stop */ private void stopAllNodesExcept(int nodeIdx) { for (int i = 0; i < GRID_COUNT; ++i) if (i != nodeIdx) stopGrid(i); } /** * @param nodeIdx Node index to not stop * @throws Exception If failed. */ private void startAllNodesExcept(int nodeIdx) throws Exception { for (int i = 0; i < GRID_COUNT; ++i) if (i != nodeIdx) startGrid(i); } }