IGNITE-944: HTTP REST log command doesn't work. This closes #383
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/05677038 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/05677038 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/05677038 Branch: refs/heads/ignite-gg-10837 Commit: 0567703827b7c8415c3e840b37e81a1ce8dbfc29 Parents: 2d10630 Author: Saikat Maitra <[email protected]> Authored: Wed Jan 20 11:07:09 2016 +0300 Committer: Denis Magda <[email protected]> Committed: Wed Jan 20 11:07:09 2016 +0300 ---------------------------------------------------------------------- modules/core/pom.xml | 3 + .../processors/rest/GridRestProcessor.java | 3 + .../handlers/log/GridLogCommandHandler.java | 176 +++++++++++++++++++ .../rest/request/GridRestLogRequest.java | 10 +- .../handlers/log/GridLogCommandHandlerTest.java | 146 +++++++++++++++ .../testsuites/IgniteRestHandlerTestSuite.java | 4 +- 6 files changed, 340 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/05677038/modules/core/pom.xml ---------------------------------------------------------------------- diff --git a/modules/core/pom.xml b/modules/core/pom.xml index b07a754..bdf822b 100644 --- a/modules/core/pom.xml +++ b/modules/core/pom.xml @@ -229,6 +229,9 @@ <exclude>**/*.java</exclude> </excludes> </testResource> + <testResource> + <directory>src/test/resources</directory> + </testResource> </testResources> <plugins> http://git-wip-us.apache.org/repos/asf/ignite/blob/05677038/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java index e839443..6d20547 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java @@ -44,6 +44,7 @@ import org.apache.ignite.internal.processors.rest.client.message.GridClientTaskR import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.datastructures.DataStructuresCommandHandler; +import org.apache.ignite.internal.processors.rest.handlers.log.GridLogCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.query.QueryCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.task.GridTaskCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.top.GridTopologyCommandHandler; @@ -442,6 +443,8 @@ public class GridRestProcessor extends GridProcessorAdapter { addHandler(new GridVersionCommandHandler(ctx)); addHandler(new DataStructuresCommandHandler(ctx)); addHandler(new QueryCommandHandler(ctx)); + addHandler(new GridLogCommandHandler(ctx)); + // Start protocols. startTcpProtocol(); http://git-wip-us.apache.org/repos/asf/ignite/blob/05677038/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandler.java new file mode 100644 index 0000000..2f8529d --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandler.java @@ -0,0 +1,176 @@ +/* + * 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.rest.handlers.log; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.net.URI; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.processors.rest.GridRestCommand; +import org.apache.ignite.internal.processors.rest.GridRestResponse; +import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandlerAdapter; +import org.apache.ignite.internal.processors.rest.request.GridRestLogRequest; +import org.apache.ignite.internal.processors.rest.request.GridRestRequest; +import org.apache.ignite.internal.util.future.GridFinishedFuture; +import org.apache.ignite.internal.util.typedef.internal.U; + +import static org.apache.ignite.internal.processors.rest.GridRestCommand.LOG; + +/** + * Handler for {@link org.apache.ignite.internal.processors.rest.GridRestCommand#LOG} command. + */ +public class GridLogCommandHandler extends GridRestCommandHandlerAdapter { + /** + * Supported commands. + */ + private static final Collection<GridRestCommand> SUPPORTED_COMMANDS = U.sealList(LOG); + + /** + * Default log file name * + */ + private static final String DEFAULT_LOG_PATH = "work/log/ignite.log"; + + /** + * Default log file start line number * + */ + private static final int DEFAULT_FROM = 0; + + /** + * Default log file end line number* + */ + private static final int DEFAULT_TO = 1; + + /** + * @param ctx Context. + */ + public GridLogCommandHandler(GridKernalContext ctx) { + super(ctx); + } + + /** {@inheritDoc} */ + @Override public Collection<GridRestCommand> supportedCommands() { + return SUPPORTED_COMMANDS; + } + + /** {@inheritDoc} */ + @Override public IgniteInternalFuture<GridRestResponse> handleAsync(GridRestRequest req) { + assert req != null; + + if (req.command() == LOG) { + if (log.isDebugEnabled()) + log.debug("Handling log REST request: " + req); + + GridRestLogRequest req0 = (GridRestLogRequest)req; + + if (req0.from() < -1 || req0.to() < -1) + return new GridFinishedFuture<>(new GridRestResponse(GridRestResponse.STATUS_FAILED, + "One of the request parameters is invalid [from=" + req0.from() + ", to=" + req0.to() + ']')); + + int from; + + if (req0.from() != -1) { + if (req0.to() == -1) + return new GridFinishedFuture<>(new GridRestResponse(GridRestResponse.STATUS_FAILED, + "Request parameter 'to' is not set.")); + + from = req0.from(); + } + else + from = DEFAULT_FROM; + + + int to; + + if (req0.to() != -1) { + if (req0.from() == -1) + return new GridFinishedFuture<>(new GridRestResponse(GridRestResponse.STATUS_FAILED, + "Request parameter 'from' is not set.")); + + to = req0.to(); + } + else + to = DEFAULT_TO; + + if (from >= to) + return new GridFinishedFuture<>(new GridRestResponse(GridRestResponse.STATUS_FAILED, + "Request parameter 'from' must be less than 'to'.")); + + File logFile; + + try { + if (req0.path() != null) + logFile = new File(req0.path()); + else + logFile = new File(ctx.config().getIgniteHome() + "/" + DEFAULT_LOG_PATH); + } + catch (InvalidPathException e) { + return new GridFinishedFuture<>(new GridRestResponse(GridRestResponse.STATUS_FAILED, + "Incorrect path to a log file [msg=" + e.getMessage() + ']')); + } + + try { + String content = readLog(from, to, logFile); + + return new GridFinishedFuture<>(new GridRestResponse(content)); + } + catch (IgniteCheckedException e) { + return new GridFinishedFuture<>(new GridRestResponse(GridRestResponse.STATUS_FAILED, e.getMessage())); + } + } + + return new GridFinishedFuture<>(); + } + + /** + * Reads content from a log file. + * + * @param from Start position. + * @param to End position. + * @param logFile Log file. + * @return Content that is read. + * @throws IgniteCheckedException If failed. + */ + private String readLog(int from, int to, File logFile) throws IgniteCheckedException { + StringBuilder content = new StringBuilder(); + + try (BufferedReader reader = new BufferedReader(new FileReader(logFile))) { + String line; + + while (from <= to && (line = reader.readLine()) != null) { + content.append(line); + + from++; + } + } + catch (IOException e) { + throw new IgniteCheckedException(e); + } + + return content.toString(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/05677038/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestLogRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestLogRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestLogRequest.java index 38a9a81..944d641 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestLogRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestLogRequest.java @@ -17,6 +17,7 @@ package org.apache.ignite.internal.processors.rest.request; +import org.apache.ignite.internal.processors.rest.GridRestCommand; import org.apache.ignite.internal.util.typedef.internal.S; /** @@ -33,6 +34,13 @@ public class GridRestLogRequest extends GridRestRequest { private int to = -1; /** + * Constructor. + */ + public GridRestLogRequest() { + command(GridRestCommand.LOG); + } + + /** * @return Path to log file. */ public String path() { @@ -78,4 +86,4 @@ public class GridRestLogRequest extends GridRestRequest { @Override public String toString() { return S.toString(GridRestLogRequest.class, this, super.toString()); } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/05677038/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandlerTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandlerTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandlerTest.java new file mode 100644 index 0000000..cc673fb --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/handlers/log/GridLogCommandHandlerTest.java @@ -0,0 +1,146 @@ +/* + * 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.rest.handlers.log; + +import java.util.Collection; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.processors.rest.GridRestCommand; +import org.apache.ignite.internal.processors.rest.GridRestResponse; +import org.apache.ignite.internal.processors.rest.request.GridRestLogRequest; +import org.apache.ignite.testframework.junits.GridTestKernalContext; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * REST log command handler tests. + */ +public class GridLogCommandHandlerTest extends GridCommonAbstractTest { + /** + * @throws Exception If failed. + */ + public void testSupportedCommands() throws Exception { + GridLogCommandHandler cmdHandler = new GridLogCommandHandler(newContext()); + + Collection<GridRestCommand> commands = cmdHandler.supportedCommands(); + + assertEquals(1, commands.size()); + assertTrue(commands.contains(GridRestCommand.LOG)); + } + + /** + * @throws Exception If failed. + */ + public void testUnSupportedCommands() throws Exception { + GridLogCommandHandler cmdHandler = new GridLogCommandHandler(newContext()); + + Collection<GridRestCommand> commands = cmdHandler.supportedCommands(); + + assertEquals(1, commands.size()); + assertFalse(commands.contains(GridRestCommand.VERSION)); + } + + /** + * @throws Exception If failed. + */ + public void testHandleAsync() throws Exception { + GridLogCommandHandler cmdHandler = new GridLogCommandHandler(newContext()); + GridRestLogRequest req = new GridRestLogRequest(); + + req.to(5); + req.from(2); + + req.path(getClass().getResource("/test.log").getFile()); + + IgniteInternalFuture<GridRestResponse> resp = cmdHandler.handleAsync(req); + + assertNull(resp.result().getError()); + assertEquals(GridRestResponse.STATUS_SUCCESS, resp.result().getSuccessStatus()); + assertNotNull(resp.result().getResponse()); + } + + /** + * @throws Exception If failed. + */ + public void testHandleAsyncFromAndToNotSet() throws Exception { + GridLogCommandHandler cmdHandler = new GridLogCommandHandler(newContext()); + GridRestLogRequest req = new GridRestLogRequest(); + + req.path(getClass().getResource("/test.log").getFile()); + + IgniteInternalFuture<GridRestResponse> resp = cmdHandler.handleAsync(req); + + assertNull(resp.result().getError()); + assertEquals(GridRestResponse.STATUS_SUCCESS, resp.result().getSuccessStatus()); + assertNotNull(resp.result().getResponse()); + } + + /** + * @throws Exception If failed. + */ + public void testHandleAsyncPathNotSet() throws Exception { + GridTestKernalContext ctx = newContext(); + ctx.config().setIgniteHome(getClass().getResource("/").getFile()); + + GridLogCommandHandler cmdHandler = new GridLogCommandHandler(ctx); + GridRestLogRequest req = new GridRestLogRequest(); + + req.to(5); + req.from(2); + + IgniteInternalFuture<GridRestResponse> resp = cmdHandler.handleAsync(req); + + assertNull(resp.result().getError()); + assertEquals(GridRestResponse.STATUS_SUCCESS, resp.result().getSuccessStatus()); + assertNotNull(resp.result().getResponse()); + } + + /** + * @throws Exception If failed. + */ + public void testHandleAsyncFromGreaterThanTo() throws Exception { + GridLogCommandHandler cmdHandler = new GridLogCommandHandler(newContext()); + GridRestLogRequest req = new GridRestLogRequest(); + + req.to(2); + req.from(5); + req.path(getClass().getResource("/test.log").getFile()); + + + IgniteInternalFuture<GridRestResponse> resp = cmdHandler.handleAsync(req); + + assertEquals("Request parameter 'from' must be less than 'to'.", resp.result().getError()); + assertEquals(GridRestResponse.STATUS_FAILED, resp.result().getSuccessStatus()); + assertNull(resp.result().getResponse()); + } + + /** + * @throws Exception If failed. + */ + public void testHandleAsyncFromEqualTo() throws Exception { + GridLogCommandHandler cmdHandler = new GridLogCommandHandler(newContext()); + GridRestLogRequest req = new GridRestLogRequest(); + + req.to(2); + req.from(2); + req.path(getClass().getResource("/test.log").getFile()); + + IgniteInternalFuture<GridRestResponse> resp = cmdHandler.handleAsync(req); + + assertEquals("Request parameter 'from' must be less than 'to'.", resp.result().getError()); + assertEquals(GridRestResponse.STATUS_FAILED, resp.result().getSuccessStatus()); + assertNull(resp.result().getResponse()); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/05677038/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteRestHandlerTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteRestHandlerTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteRestHandlerTestSuite.java index 73a2c1b..d5de376 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteRestHandlerTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteRestHandlerTestSuite.java @@ -19,6 +19,7 @@ package org.apache.ignite.testsuites; import junit.framework.TestSuite; import org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheCommandHandlerSelfTest; +import org.apache.ignite.internal.processors.rest.handlers.log.GridLogCommandHandlerTest; /** * REST support tests. @@ -32,7 +33,8 @@ public class IgniteRestHandlerTestSuite extends TestSuite { TestSuite suite = new TestSuite("REST Support Test Suite"); suite.addTestSuite(GridCacheCommandHandlerSelfTest.class); + suite.addTestSuite(GridLogCommandHandlerTest.class); return suite; } -} \ No newline at end of file +}
