Fix REST authentication.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f025714e Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f025714e Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f025714e Branch: refs/heads/ignite-1.4.2 Commit: f025714ef0d21ffff7ebf6088c254f26dd9aa3fc Parents: f60cba7 Author: ashutak <ashu...@gridgain.com> Authored: Wed Oct 7 16:11:18 2015 +0300 Committer: ashutak <ashu...@gridgain.com> Committed: Wed Oct 7 16:11:18 2015 +0300 ---------------------------------------------------------------------- .../JettyRestProcessorAbstractSelfTest.java | 27 +- .../apache/ignite/IgniteSystemProperties.java | 3 + .../processors/rest/GridRestProcessor.java | 356 +++++++++++++++++-- .../handlers/cache/GridCacheCommandHandler.java | 2 +- .../ignite/internal/util/IgniteUtils.java | 2 +- 5 files changed, 341 insertions(+), 49 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/f025714e/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java index 8db4cd7..ac0edff 100644 --- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java @@ -84,6 +84,13 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro protected abstract int restPort(); /** + * @return Security enabled flag. Should be the same with {@code ctx.security().enabled()}. + */ + protected boolean securityEnabled() { + return false; + } + + /** * @param params Command parameters. * @return Returned content. * @throws Exception If failed. @@ -133,7 +140,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro return "\\{\\\"affinityNodeId\\\":\\\"\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}\\\"\\," + "\\\"error\\\":\\\"\\\"\\," + "\\\"response\\\":\\\"" + res + "\\\"\\," + - "\\\"sessionToken\\\":\\\"\\\"," + + "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," + "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}"; } @@ -157,7 +164,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro private String integerPattern(int res, boolean success) { return "\\{\\\"error\\\":\\\"\\\"\\," + "\\\"response\\\":" + res + "\\," + - "\\\"sessionToken\\\":\\\"\\\"," + + "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," + "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}"; } @@ -170,7 +177,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro return "\\{\\\"affinityNodeId\\\":\\\"\\\"\\," + "\\\"error\\\":\\\"\\\"\\," + "\\\"response\\\":" + res + "\\," + - "\\\"sessionToken\\\":\\\"\\\"," + + "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," + "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}"; } @@ -183,7 +190,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro return "\\{\\\"affinityNodeId\\\":\\\"\\\"\\," + "\\\"error\\\":\\\"\\\"\\," + "\\\"response\\\":" + res + "\\," + - "\\\"sessionToken\\\":\\\"\\\"," + + "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," + "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}"; } @@ -196,7 +203,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro return "\\{\\\"affinityNodeId\\\":\\\"\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}\\\"\\," + "\\\"error\\\":\\\"\\\"\\," + "\\\"response\\\":" + res + "\\," + - "\\\"sessionToken\\\":\\\"\\\"," + + "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," + "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}"; } @@ -209,7 +216,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro return "\\{\\\"affinityNodeId\\\":\\\"\\\"\\," + "\\\"error\\\":\\\"\\\"\\," + "\\\"response\\\":" + res + "\\," + - "\\\"sessionToken\\\":\\\"\\\"," + + "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," + "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}"; } @@ -222,7 +229,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro return "\\{\\\"affinityNodeId\\\":\\\"(\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})?\\\"\\," + "\\\"error\\\":\\\"\\\"\\," + "\\\"response\\\":" + res + "\\," + - "\\\"sessionToken\\\":\\\"\\\"," + + "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," + "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}"; } @@ -234,7 +241,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro private String pattern(String res, boolean success) { return "\\{\\\"error\\\":\\\"" + (!success ? ".+" : "") + "\\\"\\," + "\\\"response\\\":" + res + "\\," + - "\\\"sessionToken\\\":\\\"\\\"," + + "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," + "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}"; } @@ -246,7 +253,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro private String stringPattern(String res, boolean success) { return "\\{\\\"error\\\":\\\"" + (!success ? ".+" : "") + "\\\"\\," + "\\\"response\\\":\\\"" + res + "\\\"\\," + - "\\\"sessionToken\\\":\\\"\\\"," + + "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," + "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}"; } @@ -1316,4 +1323,4 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro return id; } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/f025714e/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java index 1e4c8b7..5d3b08b 100644 --- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java +++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java @@ -96,6 +96,9 @@ public final class IgniteSystemProperties { */ public static final String IGNITE_JETTY_LOG_NO_OVERRIDE = "IGNITE_JETTY_LOG_NO_OVERRIDE"; + /** This property allow rewriting default ({@code 30}) rest session expire time (in seconds). */ + public static final String IGNITE_REST_SESSION_TIMEOUT = "IGNITE_REST_SESSION_TIMEOUT"; + /** * This property allows to override maximum count of task results stored on one node * in REST processor. http://git-wip-us.apache.org/repos/asf/ignite/blob/f025714e/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 d606ba4..d54c8bb 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 @@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.rest; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.EnumMap; import java.util.HashMap; @@ -30,7 +31,9 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.atomic.AtomicLong; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteSystemProperties; import org.apache.ignite.configuration.ConnectorConfiguration; import org.apache.ignite.configuration.ConnectorMessageInterceptor; import org.apache.ignite.internal.GridKernalContext; @@ -53,8 +56,10 @@ import org.apache.ignite.internal.processors.security.SecurityContext; import org.apache.ignite.internal.util.GridSpinReadWriteLock; import org.apache.ignite.internal.util.future.GridFinishedFuture; import org.apache.ignite.internal.util.typedef.C1; +import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.X; import org.apache.ignite.internal.util.typedef.internal.LT; +import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.util.worker.GridWorker; import org.apache.ignite.internal.util.worker.GridWorkerFuture; @@ -65,6 +70,7 @@ import org.apache.ignite.plugin.security.AuthenticationContext; import org.apache.ignite.plugin.security.SecurityCredentials; import org.apache.ignite.plugin.security.SecurityException; import org.apache.ignite.plugin.security.SecurityPermission; +import org.apache.ignite.thread.IgniteThread; import org.jsr166.LongAdder8; import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_AUTH_FAILED; @@ -80,8 +86,11 @@ public class GridRestProcessor extends GridProcessorAdapter { private static final String HTTP_PROTO_CLS = "org.apache.ignite.internal.processors.rest.protocols.http.jetty.GridJettyRestProtocol"; - /** */ - public static final byte[] ZERO_BYTES = new byte[0]; + /** Delay between sessions timeout checks. */ + private static final int SES_TIMEOUT_CHECK_DELAY = 1_000; + + /** Default session timout. */ + private static final int DEFAULT_SES_TIMEOUT = 30_000; /** Protocols. */ private final Collection<GridRestProtocol> protos = new ArrayList<>(); @@ -98,8 +107,14 @@ public class GridRestProcessor extends GridProcessorAdapter { /** Workers count. */ private final LongAdder8 workersCnt = new LongAdder8(); - /** SecurityContext map. */ - private ConcurrentMap<UUID, SecurityContext> sesMap = new ConcurrentHashMap<>(); + /** ClientId-SessionId map. */ + private final ConcurrentMap<UUID, UUID> clientId2SesId = new ConcurrentHashMap<>(); + + /** SessionId-Session map. */ + private final ConcurrentMap<UUID, Session> sesId2Ses = new ConcurrentHashMap<>(); + + /** */ + private final Thread sesTimeoutCheckerThread; /** Protocol handler. */ private final GridRestProtocolHandler protoHnd = new GridRestProtocolHandler() { @@ -112,6 +127,9 @@ public class GridRestProcessor extends GridProcessorAdapter { } }; + /** Session time to live. */ + private final long sesTtl; + /** * @param req Request. * @return Future. @@ -195,22 +213,40 @@ public class GridRestProcessor extends GridProcessorAdapter { if (log.isDebugEnabled()) log.debug("Received request from client: " + req); - SecurityContext subjCtx = null; - if (ctx.security().enabled()) { + Session ses; + try { - subjCtx = authenticate(req); + ses = session(req); + } + catch (IgniteCheckedException e) { + GridRestResponse res = new GridRestResponse(STATUS_FAILED, e.getMessage()); - authorize(req, subjCtx); + return new GridFinishedFuture<>(res); + } + + assert ses != null; + + req.clientId(ses.clientId); + req.sessionToken(U.uuidToBytes(ses.sesId)); + + if (log.isDebugEnabled()) + log.debug("Next clientId and sessionToken were extracted according to request: " + + "[clientId="+req.clientId()+", sesTok="+Arrays.toString(req.sessionToken())+"]"); + + SecurityContext secCtx0 = ses.secCtx; + + try { + if (secCtx0 == null) + ses.secCtx = secCtx0 = authenticate(req); + + authorize(req, secCtx0); } catch (SecurityException e) { - assert subjCtx != null; + assert secCtx0 != null; GridRestResponse res = new GridRestResponse(STATUS_SECURITY_CHECK_FAILED, e.getMessage()); - updateSession(req, subjCtx); - res.sessionTokenBytes(ZERO_BYTES); - return new GridFinishedFuture<>(res); } catch (IgniteCheckedException e) { @@ -228,16 +264,18 @@ public class GridRestProcessor extends GridProcessorAdapter { return new GridFinishedFuture<>( new IgniteCheckedException("Failed to find registered handler for command: " + req.command())); - final SecurityContext subjCtx0 = subjCtx; - return res.chain(new C1<IgniteInternalFuture<GridRestResponse>, GridRestResponse>() { @Override public GridRestResponse apply(IgniteInternalFuture<GridRestResponse> f) { GridRestResponse res; + boolean failed = false; + try { res = f.get(); } catch (Exception e) { + failed = true; + if (!X.hasCause(e, VisorClusterGroupEmptyException.class)) LT.error(log, e, "Failed to handle request: " + req.command()); @@ -249,10 +287,8 @@ public class GridRestProcessor extends GridProcessorAdapter { assert res != null; - if (ctx.security().enabled()) { - updateSession(req, subjCtx0); - res.sessionTokenBytes(ZERO_BYTES); - } + if (ctx.security().enabled() && !failed) + res.sessionTokenBytes(req.sessionToken()); interceptResponse(res, req); @@ -262,10 +298,137 @@ public class GridRestProcessor extends GridProcessorAdapter { } /** + * @param req Request. + * @return Not null session. + * @throws IgniteCheckedException If failed. + */ + private Session session(final GridRestRequest req) throws IgniteCheckedException { + final UUID clientId = req.clientId(); + final byte[] sesTok = req.sessionToken(); + + while (true) { + if (F.isEmpty(sesTok) && clientId == null) { + Session ses = Session.random(); + + UUID oldSesId = clientId2SesId.put(ses.clientId, ses.sesId); + + assert oldSesId == null : "Got an illegal state for request: " + req; + + Session oldSes = sesId2Ses.put(ses.sesId, ses); + + assert oldSes == null : "Got an illegal state for request: " + req; + + return ses; + } + + if (F.isEmpty(sesTok) && clientId != null) { + UUID sesId = clientId2SesId.get(clientId); + + if (sesId == null) { + Session ses = Session.fromClientId(clientId); + + if (clientId2SesId.putIfAbsent(ses.clientId, ses.sesId) != null) + continue; // Another thread already register session with the clientId. + + Session prevSes = sesId2Ses.put(ses.sesId, ses); + + assert prevSes == null : "Got an illegal state for request: " + req; + + return ses; + } + else { + Session ses = sesId2Ses.get(sesId); + + if (ses == null || !ses.touch()) + continue; // Need to wait while timeout thread complete removing of timed out sessions. + + return ses; + } + } + + if (!F.isEmpty(sesTok) && clientId == null) { + UUID sesId = U.bytesToUuid(sesTok, 0); + + Session ses = sesId2Ses.get(sesId); + + if (ses == null) + throw new IgniteCheckedException("Failed to handle request - unknown session token " + + "(maybe expired session) [sesTok=" + U.byteArray2HexString(sesTok) + "]"); + + if (!ses.touch()) + continue; // Need to wait while timeout thread complete removing of timed out sessions. + + return ses; + } + + if (!F.isEmpty(sesTok) && clientId != null) { + UUID sesId = clientId2SesId.get(clientId); + + if (sesId == null || !sesId.equals(U.bytesToUuid(sesTok, 0))) + throw new IgniteCheckedException("Failed to handle request - unsupported case (misamatched " + + "clientId and session token) [clientId=" + clientId + ", sesTok=" + + U.byteArray2HexString(sesTok) + "]"); + + Session ses = sesId2Ses.get(sesId); + + if (ses == null) + throw new IgniteCheckedException("Failed to handle request - unknown session token " + + "(maybe expired session) [sesTok=" + U.byteArray2HexString(sesTok) + "]"); + + if (!ses.touch()) + continue; // Need to wait while timeout thread complete removing of timed out sessions. + + return ses; + } + + assert false : "Got an unreachable state."; + } + } + + /** * @param ctx Context. */ public GridRestProcessor(GridKernalContext ctx) { super(ctx); + + long sesExpTime0; + String sesExpTime = null; + + try { + sesExpTime = System.getProperty(IgniteSystemProperties.IGNITE_REST_SESSION_TIMEOUT); + + if (sesExpTime != null) + sesExpTime0 = Long.valueOf(sesExpTime) * 1000; + else + sesExpTime0 = DEFAULT_SES_TIMEOUT; + } + catch (NumberFormatException ignore) { + U.warn(log, "Failed parsing IGNITE_REST_SESSION_TIMEOUT system variable [IGNITE_REST_SESSION_TIMEOUT=" + + sesExpTime + "]"); + + sesExpTime0 = DEFAULT_SES_TIMEOUT; + } + + sesTtl = sesExpTime0; + + sesTimeoutCheckerThread = new IgniteThread(ctx.gridName(), "session-timeout-worker", + new GridWorker(ctx.gridName(), "session-timeout-worker", log) { + @Override protected void body() throws InterruptedException { + while (!isCancelled()) { + Thread.sleep(SES_TIMEOUT_CHECK_DELAY); + + for (Map.Entry<UUID, Session> e : sesId2Ses.entrySet()) { + Session ses = e.getValue(); + + if (ses.isTimedOut(sesTtl)) { + sesId2Ses.remove(ses.sesId, ses); + + clientId2SesId.remove(ses.clientId, ses.sesId); + } + } + } + } + }); } /** {@inheritDoc} */ @@ -310,6 +473,10 @@ public class GridRestProcessor extends GridProcessorAdapter { for (GridRestProtocol proto : protos) proto.onKernalStart(); + sesTimeoutCheckerThread.setDaemon(true); + + sesTimeoutCheckerThread.start(); + startLatch.countDown(); if (log.isDebugEnabled()) @@ -334,6 +501,8 @@ public class GridRestProcessor extends GridProcessorAdapter { } } + U.interrupt(sesTimeoutCheckerThread); + if (interrupted) Thread.currentThread().interrupt(); @@ -483,13 +652,8 @@ public class GridRestProcessor extends GridProcessorAdapter { * @throws IgniteCheckedException If authentication failed. */ private SecurityContext authenticate(GridRestRequest req) throws IgniteCheckedException { - UUID clientId = req.clientId(); - SecurityContext secCtx = clientId == null ? null : sesMap.get(clientId); + assert req.clientId() != null; - if (secCtx != null) - return secCtx; - - // Authenticate client if invalid session. AuthenticationContext authCtx = new AuthenticationContext(); authCtx.subjectType(REMOTE_CLIENT); @@ -531,18 +695,6 @@ public class GridRestProcessor extends GridProcessorAdapter { } /** - * Update session. - * @param req REST request. - * @param sCtx Security context. - */ - private void updateSession(GridRestRequest req, SecurityContext sCtx) { - if (sCtx != null) { - UUID id = req.clientId(); - sesMap.put(id, sCtx); - } - } - - /** * @param req REST request. * @param sCtx Security context. * @throws SecurityException If authorization failed. @@ -719,4 +871,134 @@ public class GridRestProcessor extends GridProcessorAdapter { X.println(">>> protosSize: " + protos.size()); X.println(">>> handlersSize: " + handlers.size()); } -} \ No newline at end of file + + /** + * Session. + */ + private static class Session { + /** Expiration flag. It's a final state of lastToucnTime. */ + private static final Long TIMEDOUT_FLAG = 0L; + + /** Client id. */ + private final UUID clientId; + + /** Session token id. */ + private final UUID sesId; + + /** Security context. */ + private volatile SecurityContext secCtx; + + /** + * Time when session is used last time. + * If this time was set at TIMEDOUT_FLAG, then it should never be changed. + */ + private final AtomicLong lastTouchTime = new AtomicLong(U.currentTimeMillis()); + + /** + * @param clientId Client ID. + * @param sesId session ID. + */ + private Session(UUID clientId, UUID sesId) { + this.clientId = clientId; + this.sesId = sesId; + } + + /** + * Static constructor. + * + * @return New session instance with random client ID and random session ID. + */ + static Session random() { + return new Session(UUID.randomUUID(), UUID.randomUUID()); + } + + /** + * Static constructor. + * + * @param clientId Client ID. + * @return New session instance with given client ID and random session ID. + */ + static Session fromClientId(UUID clientId) { + return new Session(clientId, UUID.randomUUID()); + } + + /** + * Static constructor. + * + * @param sesTokId Session token ID. + * @return New session instance with random client ID and given session ID. + */ + static Session fromSessionToken(UUID sesTokId) { + return new Session(UUID.randomUUID(), sesTokId); + } + + /** + * Checks expiration of session and if expired then sets TIMEDOUT_FLAG. + * + * @param sesTimeout Session timeout. + * @return <code>True</code> if expired. + * @see #touch() + */ + boolean isTimedOut(long sesTimeout) { + long time0 = lastTouchTime.get(); + + if (time0 == TIMEDOUT_FLAG) + return true; + + return U.currentTimeMillis() - time0 > sesTimeout && lastTouchTime.compareAndSet(time0, TIMEDOUT_FLAG); + } + + /** + * Checks whether session at expired state (EPIRATION_FLAG) or not, if not then tries to update last touch time. + * + * @return {@code False} if session timed out (not successfully touched). + * @see #isTimedOut(long) + */ + boolean touch() { + while (true) { + long time0 = lastTouchTime.get(); + + if (time0 == TIMEDOUT_FLAG) + return false; + + boolean success = lastTouchTime.compareAndSet(time0, U.currentTimeMillis()); + + if (success) + return true; + } + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof Session)) + return false; + + Session ses = (Session)o; + + if (clientId != null ? !clientId.equals(ses.clientId) : ses.clientId != null) + return false; + + if (sesId != null ? !sesId.equals(ses.sesId) : ses.sesId != null) + return false; + + return true; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + int res = clientId != null ? clientId.hashCode() : 0; + + res = 31 * res + (sesId != null ? sesId.hashCode() : 0); + + return res; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(Session.class, this); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/f025714e/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java index b3af2f2..9d32c17 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java @@ -1391,4 +1391,4 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter { return c.sizeAsync(new CachePeekMode[]{CachePeekMode.PRIMARY}); } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/f025714e/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index e5090cb..3c1913a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -9302,4 +9302,4 @@ public abstract class IgniteUtils { throw new IgniteInterruptedCheckedException(e); } } -} \ No newline at end of file +}