Skip to content

Commit 8244269

Browse files
committed
1 parent a9a1fec commit 8244269

File tree

40 files changed

+1487
-374
lines changed

40 files changed

+1487
-374
lines changed

modules/clients/src/test/java/org/apache/ignite/common/ComputeTaskPermissionsTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@
5050
import org.apache.ignite.internal.IgniteEx;
5151
import org.apache.ignite.internal.management.cache.VerifyBackupPartitionsTask;
5252
import org.apache.ignite.internal.processors.security.AbstractSecurityTest;
53-
import org.apache.ignite.internal.processors.security.OperationSecurityContext;
5453
import org.apache.ignite.internal.processors.security.PublicAccessJob;
5554
import org.apache.ignite.internal.processors.security.SecurityContext;
5655
import org.apache.ignite.internal.processors.security.compute.ComputePermissionCheckTest;
5756
import org.apache.ignite.internal.processors.security.impl.TestSecurityData;
5857
import org.apache.ignite.internal.processors.security.impl.TestSecurityPluginProvider;
58+
import org.apache.ignite.internal.thread.context.Scope;
5959
import org.apache.ignite.internal.util.lang.ConsumerX;
6060
import org.apache.ignite.internal.util.lang.RunnableX;
6161
import org.apache.ignite.internal.util.lang.gridfunc.AtomicIntegerFactoryCallable;
@@ -379,7 +379,7 @@ public void testSystemTaskCancel() throws Exception {
379379
SecurityContext initiatorSecCtx = securityContext("no-permissions-login-0");
380380

381381
SupplierX<Future<?>> starter = () -> {
382-
try (OperationSecurityContext ignored1 = grid(0).context().security().withContext(initiatorSecCtx)) {
382+
try (Scope ignored1 = grid(0).context().security().withContext(initiatorSecCtx)) {
383383
return new TestFutureAdapter<>(
384384
grid(0).context().closure().runAsync(
385385
BROADCAST,
@@ -429,7 +429,7 @@ private void checkTaskCancel(
429429
assertTrue(taskStartedLatch.await(getTestTimeout(), MILLISECONDS));
430430

431431
try (
432-
OperationSecurityContext ignored = initiator == null
432+
Scope ignored = initiator == null
433433
? null
434434
: grid(0).context().security().withContext(initiator)
435435
) {
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.internal.thread.context;
19+
20+
import java.util.NoSuchElementException;
21+
import java.util.concurrent.atomic.AtomicInteger;
22+
23+
/** */
24+
public class ContextAttribute<T> {
25+
/** */
26+
static final AtomicInteger ID_GEN = new AtomicInteger();
27+
28+
/** */
29+
static final int MAX_ATTRIBUTE_CNT = Integer.SIZE;
30+
31+
/** */
32+
private final byte id;
33+
34+
/** */
35+
private final int bitmask;
36+
37+
/** */
38+
private ContextAttribute(byte id) {
39+
this.id = id;
40+
this.bitmask = 1 << id;
41+
}
42+
43+
/** */
44+
byte id() {
45+
return id;
46+
}
47+
48+
/** */
49+
int bitmask() {
50+
return bitmask;
51+
}
52+
53+
/** */
54+
public boolean isAttached() {
55+
return ThreadLocalContextStorage.get().findScopedContextFor(this) != null;
56+
}
57+
58+
/** */
59+
public T get() {
60+
ScopedContext sc = ThreadLocalContextStorage.get().findScopedContextFor(this);
61+
62+
if (sc == null)
63+
throw new NoSuchElementException();
64+
65+
return (T)sc.value();
66+
}
67+
68+
/** */
69+
public T orElse(T other) {
70+
ScopedContext sc = ThreadLocalContextStorage.get().findScopedContextFor(this);
71+
72+
return sc == null ? other : (T)sc.value();
73+
}
74+
75+
/** */
76+
public static <T> ContextAttribute<T> newInstance() {
77+
int id = ID_GEN.getAndIncrement();
78+
79+
if (MAX_ATTRIBUTE_CNT <= id) {
80+
throw new RuntimeException("Exceeded maximum supported number of created Context Attributes instances" +
81+
" [maxCnt=" + MAX_ATTRIBUTE_CNT + ']');
82+
}
83+
84+
return new ContextAttribute<>((byte)id);
85+
}
86+
87+
/** */
88+
static int highReservedId() {
89+
return ID_GEN.get();
90+
}
91+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.internal.thread.context;
19+
20+
import java.util.function.BiFunction;
21+
import org.apache.ignite.internal.IgniteInternalWrapper;
22+
23+
/** */
24+
public abstract class ContextAwareWrapper<T> implements IgniteInternalWrapper<T> {
25+
/** */
26+
protected final T delegate;
27+
28+
/** */
29+
protected final ContextSnapshot snapshot;
30+
31+
/** */
32+
@Override public T delegate() {
33+
return delegate;
34+
}
35+
36+
/** */
37+
protected ContextAwareWrapper(T delegate, ContextSnapshot snapshot) {
38+
this.delegate = delegate;
39+
this.snapshot = snapshot;
40+
}
41+
42+
/** */
43+
protected static <T> T wrap(T delegate, BiFunction<T, ContextSnapshot, T> wrapper) {
44+
return wrap(delegate, wrapper, false);
45+
}
46+
47+
/** */
48+
protected static <T> T wrap(T delegate, BiFunction<T, ContextSnapshot, T> wrapper, boolean ignoreEmptyContext) {
49+
if (delegate == null || delegate instanceof ContextAwareWrapper)
50+
return delegate;
51+
52+
ContextSnapshot snapshot = ContextSnapshot.capture();
53+
54+
if (ignoreEmptyContext && snapshot.isEmpty())
55+
return delegate;
56+
57+
return wrapper.apply(delegate, snapshot);
58+
}
59+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.internal.thread.context;
19+
20+
/** */
21+
public abstract class ContextDataChain<T> {
22+
/** */
23+
private final int storedAttrBits;
24+
25+
/** */
26+
private final T prev;
27+
28+
/** */
29+
protected ContextDataChain() {
30+
storedAttrBits = 0;
31+
prev = null;
32+
}
33+
34+
/** */
35+
protected ContextDataChain(int storedAttrBits, T prev) {
36+
this.storedAttrBits = storedAttrBits;
37+
this.prev = prev;
38+
}
39+
40+
/** */
41+
abstract boolean isEmpty();
42+
43+
/** */
44+
int storedAttributeBits() {
45+
return storedAttrBits;
46+
}
47+
48+
/** */
49+
boolean containsValueFor(ContextAttribute<?> attr) {
50+
return (storedAttrBits & attr.bitmask()) != 0;
51+
}
52+
53+
/** */
54+
T previous() {
55+
assert !isEmpty();
56+
57+
return prev;
58+
}
59+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.internal.thread.context;
19+
20+
/** */
21+
public class ContextSnapshot extends ContextDataChain<ContextSnapshot> {
22+
/** */
23+
static final ContextSnapshot ROOT = new ContextSnapshot();
24+
25+
/** */
26+
private final ScopedContext scopedCtx;
27+
28+
/** */
29+
private ContextSnapshot() {
30+
scopedCtx = null;
31+
}
32+
33+
/** */
34+
private ContextSnapshot(ScopedContext scopedCtx, ContextSnapshot prev) {
35+
super(scopedCtx.storedAttributeBits() | prev.storedAttributeBits(), prev);
36+
37+
this.scopedCtx = scopedCtx;
38+
}
39+
40+
/** */
41+
public Scope restore() {
42+
ThreadLocalContextStorage threadData = ThreadLocalContextStorage.get();
43+
44+
ContextSnapshot prev = threadData.snapshot();
45+
46+
threadData.reinitialize(this);
47+
48+
return () -> {
49+
ThreadLocalContextStorage td = ThreadLocalContextStorage.get();
50+
51+
assert td.snapshot() == this : "Scopes must be closed in the same order and in the same thread they are opened";
52+
53+
td.reinitialize(prev);
54+
};
55+
}
56+
57+
/** */
58+
ContextSnapshot attach(ScopedContext scopedCtx) {
59+
return new ContextSnapshot(scopedCtx, this);
60+
}
61+
62+
/** */
63+
ScopedContext scopedContext() {
64+
assert !isEmpty();
65+
66+
return scopedCtx;
67+
}
68+
69+
/** {@inheritDoc} */
70+
@Override boolean isEmpty() {
71+
return this == ROOT;
72+
}
73+
74+
/** */
75+
public static ContextSnapshot capture() {
76+
return ThreadLocalContextStorage.get().snapshot();
77+
}
78+
}

modules/core/src/main/java/org/apache/ignite/internal/processors/security/OperationSecurityContext.java renamed to modules/commons/src/main/java/org/apache/ignite/internal/thread/context/Scope.java

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,17 @@
1515
* limitations under the License.
1616
*/
1717

18-
package org.apache.ignite.internal.processors.security;
18+
package org.apache.ignite.internal.thread.context;
1919

20-
/**
21-
*
22-
*/
23-
public class OperationSecurityContext implements AutoCloseable {
24-
/** Ignite Security. */
25-
private final IgniteSecurity proc;
26-
27-
/** Security context. */
28-
private final SecurityContext secCtx;
29-
30-
/**
31-
* @param proc Ignite Security.
32-
* @param secCtx Security context.
33-
*/
34-
OperationSecurityContext(IgniteSecurity proc, SecurityContext secCtx) {
35-
this.proc = proc;
36-
this.secCtx = secCtx;
37-
}
20+
/** */
21+
public interface Scope extends AutoCloseable {
22+
/** */
23+
Scope NOOP_SCOPE = new Scope() {
24+
@Override public void close() {
25+
// No-op.
26+
}
27+
};
3828

3929
/** {@inheritDoc} */
40-
@Override public void close() {
41-
if (secCtx == null)
42-
((IgniteSecurityProcessor)proc).restoreDefaultContext();
43-
else
44-
proc.withContext(secCtx);
45-
}
30+
@Override void close();
4631
}

0 commit comments

Comments
 (0)