diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 0000000000000..30d183eed2cbc --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1,10 @@ +--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/processors/cache/CacheObject.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/processors/cache/CacheObject.java index 09e7a8d5a0e91..845eb86e17402 100644 --- a/modules/binary/api/src/main/java/org/apache/ignite/internal/processors/cache/CacheObject.java +++ b/modules/binary/api/src/main/java/org/apache/ignite/internal/processors/cache/CacheObject.java @@ -120,13 +120,13 @@ public interface CacheObject { * @param ldr Class loader. * @throws IgniteCheckedException If failed. */ - public void finishUnmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException; + public void unmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException; /** * @param ctx Context. * @throws IgniteCheckedException If failed. */ - public void prepareMarshal(CacheObjectValueContext ctx) throws IgniteCheckedException; + public void marshal(CacheObjectValueContext ctx) throws IgniteCheckedException; /** * @return {@code True} if postWriteHashCode call required, {@code false} otherwise. diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java index d61cab738b414..2024eef66e521 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java @@ -367,12 +367,12 @@ private T uncachedValue(Class cls) throws BinaryObjectException { } /** {@inheritDoc} */ - @Override public void finishUnmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { + @Override public void unmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { this.ctx = ctx.binaryContext(); } /** {@inheritDoc} */ - @Override public void prepareMarshal(CacheObjectValueContext ctx) throws IgniteCheckedException { + @Override public void marshal(CacheObjectValueContext ctx) throws IgniteCheckedException { // No-op. } diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java index 50e85ff230899..7dd2bebdf86af 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java @@ -220,13 +220,13 @@ public BinaryObjectImpl(BinaryContext ctx, byte[] arr, int start) { @Override public CacheObject prepareForCache(CacheObjectValueContext ctx) { BinaryObjectImpl res = detached() ? this : detach(false); - res.prepareMarshal(ctx); + res.marshal(ctx); return res; } /** {@inheritDoc} */ - @Override public void finishUnmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { + @Override public void unmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { assert arr != null || valBytes != null; if (arr == null) @@ -238,7 +238,7 @@ public BinaryObjectImpl(BinaryContext ctx, byte[] arr, int start) { } /** {@inheritDoc} */ - @Override public void prepareMarshal(CacheObjectValueContext ctx) { + @Override public void marshal(CacheObjectValueContext ctx) { assert arr != null || valBytes != null; if (valBytes == null) diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java index cce4f59dab7fe..e2ac1b89b4e42 100644 --- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java +++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java @@ -453,12 +453,12 @@ else if (fieldOffLen == BinaryUtils.OFFSET_2) } /** {@inheritDoc} */ - @Override public void finishUnmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { + @Override public void unmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { throw new UnsupportedOperationException(); } /** {@inheritDoc} */ - @Override public void prepareMarshal(CacheObjectValueContext ctx) throws IgniteCheckedException { + @Override public void marshal(CacheObjectValueContext ctx) throws IgniteCheckedException { throw new UnsupportedOperationException(); } diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/CalciteMessageFactory.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/CalciteMessageFactory.java index d15b5821e0597..cec70d15ee4fd 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/CalciteMessageFactory.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/CalciteMessageFactory.java @@ -36,18 +36,18 @@ public class CalciteMessageFactory extends AbstractMarshallableMessageFactoryPro /** {@inheritDoc} */ @Override public void registerAll(MessageFactory factory) { - register(factory, QueryStartRequest.class, (short)300, schemaAwareMarsh, resolvedClsLdr); - register(factory, QueryStartResponse.class, (short)301, dfltMarsh, dftlClsLdr); - register(factory, CalciteErrorMessage.class, (short)302, dfltMarsh, resolvedClsLdr); - register(factory, QueryBatchMessage.class, (short)303, dfltMarsh, dftlClsLdr); - register(factory, QueryBatchAcknowledgeMessage.class, (short)304, dfltMarsh, dftlClsLdr); - register(factory, QueryInboxCloseMessage.class, (short)305, dfltMarsh, dftlClsLdr); - register(factory, QueryCloseMessage.class, (short)306, dfltMarsh, dftlClsLdr); - register(factory, GenericValueMessage.class, (short)307, schemaAwareMarsh, resolvedClsLdr); - register(factory, FragmentMapping.class, (short)308, dfltMarsh, dftlClsLdr); - register(factory, ColocationGroup.class, (short)309, dfltMarsh, dftlClsLdr); - register(factory, FragmentDescription.class, (short)310, dfltMarsh, dftlClsLdr); - register(factory, QueryTxEntry.class, (short)311, dfltMarsh, dftlClsLdr); + register(factory, QueryStartRequest.class, (short)300, schemaAwareMarsh); + register(factory, QueryStartResponse.class, (short)301, dfltMarsh); + register(factory, CalciteErrorMessage.class, (short)302, dfltMarsh); + register(factory, QueryBatchMessage.class, (short)303, dfltMarsh); + register(factory, QueryBatchAcknowledgeMessage.class, (short)304, dfltMarsh); + register(factory, QueryInboxCloseMessage.class, (short)305, dfltMarsh); + register(factory, QueryCloseMessage.class, (short)306, dfltMarsh); + register(factory, GenericValueMessage.class, (short)307, schemaAwareMarsh); + register(factory, FragmentMapping.class, (short)308, dfltMarsh); + register(factory, ColocationGroup.class, (short)309, dfltMarsh); + register(factory, FragmentDescription.class, (short)310, dfltMarsh); + register(factory, QueryTxEntry.class, (short)311, dfltMarsh); } /** */ diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/GenericValueMessage.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/GenericValueMessage.java index 40849bab6a73a..0b24aae0d40f5 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/GenericValueMessage.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/GenericValueMessage.java @@ -18,10 +18,10 @@ package org.apache.ignite.internal.processors.query.calcite.message; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; /** */ public final class GenericValueMessage implements MarshallableMessage { @@ -48,13 +48,13 @@ public Object value() { } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { if (val != null && serialized == null) serialized = U.marshal(marsh, val); } /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (serialized != null && val == null) val = U.unmarshal(marsh, serialized, clsLdr); diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java index 4c8a699ca9c68..0d386f32d957b 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java @@ -39,6 +39,7 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; /** * @@ -154,11 +155,8 @@ public FailureProcessor failureProcessor() { @Override public void send(UUID nodeId, Message msg) throws IgniteCheckedException { if (localNodeId().equals(nodeId)) onMessage(nodeId, msg); - else { - prepareMarshal(msg); - + else ioManager().sendToGridTopic(nodeId, GridTopic.TOPIC_QUERY, msg, GridIoPolicy.CALLER_THREAD); - } } /** {@inheritDoc} */ @@ -181,24 +179,10 @@ public FailureProcessor failureProcessor() { } } - /** */ - protected void prepareMarshal(Message msg) throws IgniteCheckedException { - try { - if (msg instanceof CalciteContextMarshallableMessage) - ((CalciteContextMarshallableMessage)msg).prepareMarshal(ctx); - } - catch (Exception e) { - failureProcessor().process(new FailureContext(FailureType.CRITICAL_ERROR, e)); - - throw e; - } - } - /** */ protected void prepareUnmarshal(Message msg) throws IgniteCheckedException { try { - if (msg instanceof CalciteContextMarshallableMessage) - ((CalciteContextMarshallableMessage)msg).finishUnmarshal(ctx, clsLdr); + MessageMarshaller.unmarshal(ctx.kernalContext().messageFactory(), msg, ctx.kernalContext(), null, clsLdr); } catch (Exception e) { failureProcessor().process(new FailureContext(FailureType.CRITICAL_ERROR, e)); @@ -221,22 +205,24 @@ protected void onMessage(UUID nodeId, Message msg) { ); } - /** */ + /** Listener for messages arriving from remote nodes; they are marshalled and must be finish-unmarshalled here. */ private void onMessage(UUID nodeId, Object msg, byte plc) { - if (msg instanceof Message && CalciteMessageFactory.isCalciteMessage((Message)msg)) + if (msg instanceof Message && CalciteMessageFactory.isCalciteMessage((Message)msg)) { + try { + prepareUnmarshal((Message)msg); + } + catch (IgniteCheckedException e) { + throw U.convertException(e); + } + onMessage(nodeId, (Message)msg); + } } /** */ private void onMessageInternal(UUID nodeId, Message msg) { - try { - prepareUnmarshal(msg); + MessageListener lsnr = Objects.requireNonNull(lsnrs.get(msg.getClass())); - MessageListener lsnr = Objects.requireNonNull(lsnrs.get(msg.getClass())); - lsnr.onMessage(nodeId, msg); - } - catch (IgniteCheckedException e) { - throw U.convertException(e); - } + lsnr.onMessage(nodeId, msg); } } diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryStartRequest.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryStartRequest.java index 15d34e00fbbfe..e8273b8d20661 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryStartRequest.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryStartRequest.java @@ -21,19 +21,16 @@ import java.util.Map; import java.util.UUID; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.query.calcite.metadata.FragmentDescription; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.jetbrains.annotations.Nullable; -/** - * - */ -public class QueryStartRequest implements MarshallableMessage, CalciteContextMarshallableMessage, ExecutionContextAware { +/** Message sent to remote nodes to start a query fragment execution. */ +public class QueryStartRequest implements MarshallableMessage, ExecutionContextAware { /** */ @Order(0) String schema; @@ -215,32 +212,16 @@ public boolean keepBinaryMode() { } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { if (paramsBytes == null && params != null) paramsBytes = U.marshal(marsh, params); } /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - if (qryTxEntries != null) { - for (QueryTxEntry e : qryTxEntries) - e.prepareMarshal(ctx); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (params == null && paramsBytes != null) params = U.unmarshal(marsh, paramsBytes, clsLdr); paramsBytes = null; } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader clsLdr) throws IgniteCheckedException { - if (qryTxEntries != null) { - for (QueryTxEntry e : qryTxEntries) - e.finishUnmarshal(ctx, clsLdr); - } - } } diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryTxEntry.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryTxEntry.java index 36f2d9dceee84..6f3e6e4b5afb9 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryTxEntry.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/QueryTxEntry.java @@ -20,15 +20,14 @@ import java.util.Collection; import java.util.Comparator; import java.util.function.Function; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.configuration.TransactionConfiguration; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.CacheObjectContext; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext; +import org.apache.ignite.plugin.extensions.communication.CacheIdAware; +import org.apache.ignite.plugin.extensions.communication.Message; /** * Class to pass to remote nodes transaction changes. @@ -38,7 +37,7 @@ * @see ExecutionContext#transactionChanges(int, int[], Function, Comparator) * @see QueryStartRequest#queryTransactionEntries() */ -public class QueryTxEntry implements CalciteContextMarshallableMessage { +public class QueryTxEntry implements Message, CacheIdAware { /** Cache id. */ @Order(0) int cacheId; @@ -75,8 +74,8 @@ public QueryTxEntry(int cacheId, KeyCacheObject key, CacheObject val, GridCacheV this.ver = ver; } - /** @return Cache id. */ - public int cacheId() { + /** {@inheritDoc} */ + @Override public int cacheId() { return cacheId; } @@ -94,24 +93,4 @@ public CacheObject value() { public GridCacheVersion version() { return ver; } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - CacheObjectContext coctx = ctx.cacheContext(cacheId).cacheObjectContext(); - - key.prepareMarshal(coctx); - - if (val != null) - val.prepareMarshal(coctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - CacheObjectContext coctx = ctx.cacheContext(cacheId).cacheObjectContext(); - - key.finishUnmarshal(coctx, ldr); - - if (val != null) - val.finishUnmarshal(coctx, ldr); - } } diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/ColocationGroup.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/ColocationGroup.java index 7981d736953e2..a0fd5eba4519d 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/ColocationGroup.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/ColocationGroup.java @@ -30,7 +30,6 @@ import java.util.stream.Collectors; import java.util.stream.LongStream; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState; import org.apache.ignite.internal.processors.query.calcite.util.Commons; @@ -39,6 +38,7 @@ import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; /** */ public class ColocationGroup implements MarshallableMessage { @@ -314,8 +314,8 @@ public int[] partitions(UUID nodeId) { } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (assignments == null || primaryAssignment) + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { + if (!F.isEmpty(marshalledAssignments) || assignments == null || primaryAssignment) return; Map nodeIdxs = new HashMap<>(); @@ -343,7 +343,7 @@ public int[] partitions(UUID nodeId) { } /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (F.isEmpty(marshalledAssignments)) return; diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AbstractExecutionTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AbstractExecutionTest.java index b7f5880259be2..5dd910a20c7e9 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AbstractExecutionTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AbstractExecutionTest.java @@ -399,6 +399,11 @@ private TestMessageServiceImpl(GridKernalContext kernal, TestIoManager mgr) { @Override public boolean alive(UUID nodeId) { return true; } + + /** {@inheritDoc} */ + @Override protected void prepareUnmarshal(Message msg) { + // No-op: TestIoManager delivers messages in-memory, no deserialization needed. + } } /** diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/AbstractPlannerTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/AbstractPlannerTest.java index b49af08b5c700..82ee3fab07fdd 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/AbstractPlannerTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/AbstractPlannerTest.java @@ -786,6 +786,11 @@ static class TestMessageServiceImpl extends MessageServiceImpl { @Override public boolean alive(UUID nodeId) { return true; } + + /** {@inheritDoc} */ + @Override protected void prepareUnmarshal(Message msg) { + // No-op: TestIoManager delivers messages in-memory, no deserialization needed. + } } /** */ diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/Marshalled.java b/modules/codegen/src/main/java/org/apache/ignite/internal/Marshalled.java new file mode 100644 index 0000000000000..8c814643ff8ac --- /dev/null +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/Marshalled.java @@ -0,0 +1,31 @@ +/* + * 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Marks an object field whose wire representation is a companion {@code byte[]} {@code @Order} field named by {@link #value()}. */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.FIELD) +public @interface Marshalled { + /** Name of the {@code @Order} {@code byte[]} field that holds the serialized form. */ + String value(); +} diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MarshalledCollection.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MarshalledCollection.java new file mode 100644 index 0000000000000..5cc4f4e8819a6 --- /dev/null +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MarshalledCollection.java @@ -0,0 +1,31 @@ +/* + * 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Marks a {@code Collection} field whose wire form is a companion {@code @Order} array field named by {@link #value()}. */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.FIELD) +public @interface MarshalledCollection { + /** Name of the {@code @Order} array field that holds the elements. */ + String value(); +} diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MarshalledMap.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MarshalledMap.java new file mode 100644 index 0000000000000..8204326c1e0cf --- /dev/null +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MarshalledMap.java @@ -0,0 +1,34 @@ +/* + * 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Marks a {@code Map} field whose wire form is a pair of {@code @Order} companion fields: {@link #keys()} and {@link #values()}. */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.FIELD) +public @interface MarshalledMap { + /** Name of the {@code @Order} field that holds the keys. */ + String keys(); + + /** Name of the {@code @Order} field that holds the values. */ + String values(); +} diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MarshalledObjects.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MarshalledObjects.java new file mode 100644 index 0000000000000..f64192462ea93 --- /dev/null +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MarshalledObjects.java @@ -0,0 +1,36 @@ +/* + * 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks a {@code Collection} field of arbitrary (non-{@code Message}) objects whose wire form is a companion + * {@code @Order Collection} field named by {@link #value()}: each element is marshalled to its own + * {@code byte[]}, so elements that need different deployment class loaders survive. Use {@code @MarshalledCollection} + * instead when the elements are {@code Message}s. + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.FIELD) +public @interface MarshalledObjects { + /** Name of the {@code @Order Collection} field that holds the per-element marshalled bytes. */ + String value(); +} diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageDeploymentGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageDeploymentGenerator.java new file mode 100644 index 0000000000000..82df6bd13b1f0 --- /dev/null +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageDeploymentGenerator.java @@ -0,0 +1,301 @@ +/* + * 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; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.type.WildcardType; +import javax.lang.model.util.ElementFilter; +import org.jetbrains.annotations.Nullable; + +import static org.apache.ignite.internal.systemview.SystemViewRowAttributeWalkerProcessor.superclasses; + +/** + * Generates a {@code *Deployer} class for messages whose {@code @Order} fields have a type that indicates deployment + * need: {@code CacheObject} subtypes, {@code Collection}, {@code Iterable}, or a + * nested {@code GridCacheMessage} (whose deployment is delegated). The strategy is inferred entirely from the field type. + * + *

A message with deployment logic that cannot be inferred from field types implements {@code DeployableMessage}; + * the generated deployer then also delegates to its {@code deploy}, mirroring {@code marshal}. + */ +public class MessageDeploymentGenerator extends MessageGenerator { + /** FQN of GridCacheMessage; hierarchy scan stops here (exclusive). */ + private static final String GRID_CACHE_MESSAGE = "org.apache.ignite.internal.processors.cache.GridCacheMessage"; + + /** */ + private final TypeMirror cacheIdMsgMirror; + + /** */ + private final TypeMirror cacheGroupIdMsgMirror; + + /** */ + private final TypeMirror gridCacheMessageMirror; + + /** */ + private final TypeMirror deployableMessageMirror; + + /** */ + private final TypeMirror cacheObjectMirror; + + /** */ + private final TypeMirror txEntryMirror; + + /** */ + private final TypeMirror collectionMirror; + + /** */ + private final TypeMirror iterableMirror; + + /** Accumulated source lines for the generated {@code deploy} method. */ + private final List deploy = new ArrayList<>(); + + /** */ + private boolean needsCctx; + + /** */ + MessageDeploymentGenerator(ProcessingEnvironment env) { + super(env); + + cacheIdMsgMirror = type("org.apache.ignite.internal.processors.cache.GridCacheIdMessage"); + cacheGroupIdMsgMirror = type("org.apache.ignite.internal.processors.cache.GridCacheGroupIdMessage"); + gridCacheMessageMirror = type(GRID_CACHE_MESSAGE); + deployableMessageMirror = type("org.apache.ignite.internal.processors.cache.DeployableMessage"); + cacheObjectMirror = type("org.apache.ignite.internal.processors.cache.CacheObject"); + txEntryMirror = type("org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry"); + collectionMirror = erasedType(type("java.util.Collection")); + iterableMirror = erasedType(type("java.lang.Iterable")); + } + + /** {@inheritDoc} */ + @Override String typeSuffix() { + return "Deployer"; + } + + /** {@inheritDoc} */ + @Override boolean shouldSkip(TypeElement type) { + if (gridCacheMessageMirror == null || !assignableFrom(type.asType(), gridCacheMessageMirror)) + return true; + + // Generate when the message carries custom deployment logic... + if (hasCustomDeployment(type)) + return false; + + // ...or has any field whose deployment can be inferred from its type. + for (VariableElement f : allHierarchyFields(type)) { + if (deployKind(f) != null) + return false; + } + + return true; + } + + /** @return {@code true} if {@code type} implements {@code DeployableMessage} (has hand-written {@code deploy}). */ + private boolean hasCustomDeployment(TypeElement type) { + return deployableMessageMirror != null && assignableFrom(type.asType(), deployableMessageMirror); + } + + /** {@inheritDoc} */ + @Override void generateBody(List fields) { + indent = 1; + + deploy.add(indentedLine(METHOD_JAVADOC)); + deploy.add(indentedLine( + "@Override public void deploy(%s msg, GridCacheSharedContext ctx) throws IgniteCheckedException {", + simpleNameWithGeneric(type))); + + indent++; + + List body = new ArrayList<>(); + + for (VariableElement field : allHierarchyFields(type)) { + DeployKind kind = deployKind(field); + + if (kind == null) + continue; + + String stmt; + + switch (kind) { + case CACHE_OBJECT: + needsCctx = true; + stmt = "msg.deployCacheObject(%s, cctx);"; + + break; + + case CACHE_OBJECTS: + needsCctx = true; + stmt = "msg.deployCacheObjects(%s, cctx);"; + + break; + + case TX_ENTRIES: + stmt = "msg.deployTx(%s, ctx);"; + + break; + + case NESTED: + stmt = "GridCacheMessageDeployer.deploy(ctx.kernalContext().messageFactory(), %s, ctx);"; + + break; + + default: + throw new IllegalStateException("Unexpected deploy kind: " + kind); + } + + appendBlock(body, List.of(indentedLine(stmt, fieldAccessor(field)))); + } + + if (needsCctx) { + deploy.add(indentedLine(cctxResolutionLine())); + deploy.add(EMPTY); + } + + deploy.addAll(body); + + // Delegate the non-inferable part to the message's own deploy, mirroring msg.marshal(). + if (hasCustomDeployment(type)) { + if (!body.isEmpty()) + deploy.add(EMPTY); + + deploy.add(indentedLine("msg.deploy(ctx);")); + } + + indent--; + + deploy.add(indentedLine("}")); + } + + /** {@inheritDoc} */ + @Override String buildClassCode(String deployerClsName) throws IOException { + try (Writer writer = new StringWriter()) { + imports.add(type.toString()); + imports.add("org.apache.ignite.IgniteCheckedException"); + imports.add("org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer"); + imports.add("org.apache.ignite.internal.processors.cache.GridCacheSharedContext"); + + if (needsCctx) + imports.add("org.apache.ignite.internal.processors.cache.GridCacheContext"); + + writeClassHeader(writer, "GridCacheMessageDeployer", deployerClsName); + + writer.write(" {" + NL); + + for (String line : deploy) + writer.write(line + NL); + + writer.write("}"); + + return writer.toString(); + } + } + + /** Returns the line that resolves {@code cctx} from {@code ctx} based on the message type hierarchy. */ + private String cctxResolutionLine() { + if (assignableFrom(type.asType(), cacheGroupIdMsgMirror)) + return "GridCacheContext cctx = ctx.cacheContext(msg.groupId());"; + + if (assignableFrom(type.asType(), cacheIdMsgMirror)) + return "GridCacheContext cctx = ctx.cacheContext(msg.cacheId());"; + + throw new IllegalStateException("Cannot resolve cache context for " + type.getQualifiedName() + + ": message has CacheObject field(s) but is neither GridCacheIdMessage nor GridCacheGroupIdMessage."); + } + + /** All fields declared across the class hierarchy of {@code te}, up to but excluding {@code Object}. */ + private List allHierarchyFields(TypeElement te) { + List result = new ArrayList<>(); + + superclasses(env, te).forEach(c -> result.addAll(ElementFilter.fieldsIn(c.getEnclosedElements()))); + + return result; + } + + /** Returns the deployment strategy for {@code field} based on its Java type, or {@code null} if not deployable. */ + private @Nullable DeployKind deployKind(VariableElement field) { + // Only serialized fields are sent over the wire and thus need deployment; transient fields are skipped. + if (field.getAnnotation(Order.class) == null) + return null; + + TypeMirror fieldType = field.asType(); + + if (fieldType.getKind() == TypeKind.ARRAY || fieldType.getKind().isPrimitive()) + return null; + + if (assignableFrom(fieldType, cacheObjectMirror)) + return DeployKind.CACHE_OBJECT; + + if (!(fieldType instanceof DeclaredType)) + return null; + + List args = ((DeclaredType)fieldType).getTypeArguments(); + TypeMirror erased = erasedType(fieldType); + + if (!args.isEmpty()) { + TypeMirror elemType = erasedType(elementBound(args.get(0))); + + if (assignableFrom(erased, collectionMirror) + && assignableFrom(elemType, cacheObjectMirror)) + return DeployKind.CACHE_OBJECTS; + + if (txEntryMirror != null && iterableMirror != null + && assignableFrom(erased, iterableMirror) + && env.getTypeUtils().isSameType(elemType, txEntryMirror)) + return DeployKind.TX_ENTRIES; + } + + // A nested message field delegates its own deployment (a no-op when that message has no deployer). + if (gridCacheMessageMirror != null && assignableFrom(fieldType, gridCacheMessageMirror)) + return DeployKind.NESTED; + + return null; + } + + /** Unwraps the upper bound of a wildcard type; returns the type as-is for non-wildcards. */ + private TypeMirror elementBound(TypeMirror arg) { + if (arg instanceof WildcardType) { + TypeMirror bound = ((WildcardType)arg).getExtendsBound(); + return bound != null ? bound : arg; + } + + return arg; + } + + /** Deployment strategy inferred from a field's type. */ + private enum DeployKind { + /** */ + CACHE_OBJECT, + + /** */ + CACHE_OBJECTS, + + /** */ + TX_ENTRIES, + + /** */ + NESTED + } +} diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageGenerator.java new file mode 100644 index 0000000000000..95dd26c08aa6d --- /dev/null +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageGenerator.java @@ -0,0 +1,266 @@ +/* + * 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; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.Writer; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeSet; +import javax.annotation.processing.FilerException; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; +import javax.lang.model.util.Elements; +import javax.tools.Diagnostic; +import javax.tools.FileObject; +import javax.tools.JavaFileObject; +import javax.tools.StandardLocation; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.SB; + +/** Base class for message code generators ({@link MessageSerializerGenerator}, {@link MessageMarshallerGenerator}). */ +public abstract class MessageGenerator { + /** Blank separator line in generated code. */ + public static final String EMPTY = ""; + + /** Platform line separator used in generated code. */ + public static final String NL = System.lineSeparator(); + + /** Single indentation unit. */ + public static final String TAB = " "; + + /** Javadoc stub emitted on every generated {@code @Override} method. */ + public static final String METHOD_JAVADOC = "/** */"; + + /** Javadoc block emitted on every generated class. */ + public static final String CLS_JAVADOC = "/**" + NL + + " * This class is generated automatically." + NL + + " *" + NL + + " * @see org.apache.ignite.internal.MessageProcessor" + NL + + " */"; + + /** */ + final ProcessingEnvironment env; + + /** */ + final java.util.Set imports = new TreeSet<>(); + + /** */ + TypeElement type; + + /** */ + int indent; + + /** */ + MessageGenerator(ProcessingEnvironment env) { + this.env = env; + } + + /** Generates and writes the source file for {@code type}; skipped when {@link #shouldSkip} returns {@code true}. + */ + final void generate(TypeElement type, List fields) throws Exception { + assert this.type == null : "Message" + typeSuffix() + " generator isn't stateless and is supposed to be single-use."; + + if (shouldSkip(type)) + return; + + this.type = type; + + generateBody(fields); + + String clsName = type.getSimpleName() + typeSuffix(); + String fqnClsName = env.getElementUtils().getPackageOf(type) + "." + clsName; + String code = buildClassCode(clsName); + + try { + JavaFileObject file = env.getFiler().createSourceFile(fqnClsName); + + try (Writer writer = file.openWriter()) { + writer.append(code); + writer.flush(); + } + } + catch (FilerException e) { + if (!identicalFileIsAlreadyGenerated(env, code, fqnClsName)) { + env.getMessager().printMessage(Diagnostic.Kind.ERROR, + "Message" + typeSuffix() + " " + clsName + " is already generated. Try 'mvn clean install' to fix the issue."); + + throw e; + } + } + } + + /** @return Class name suffix: {@code "Serializer"} or {@code "Marshaller"}. */ + abstract String typeSuffix(); + + /** @return {@code true} if no file should be generated for this type; default is {@code false}. */ + boolean shouldSkip(TypeElement type) { + return false; + } + + /** Populates internal state (method body lines etc.) from {@code fields}; called before {@link #buildClassCode}. + */ + abstract void generateBody(List fields) throws Exception; + + /** Generates and returns the complete source code for the generated class. */ + abstract String buildClassCode(String clsName) throws IOException; + + /** */ + void writeLicense(Writer writer) throws IOException { + try (InputStream in = getClass().getClassLoader().getResourceAsStream("license.txt"); + BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { + + PrintWriter out = new PrintWriter(writer); + String line; + + while ((line = reader.readLine()) != null) + out.println(line); + } + } + + /** Writes license, package, imports, javadoc, and class declaration; {@link #imports} must be populated before calling. */ + void writeClassHeader(Writer writer, String interfaceName, String clsName) throws IOException { + writeLicense(writer); + + writer.write(NL); + writer.write("package " + env.getElementUtils().getPackageOf(type) + ";" + NL + NL); + + for (String imp : imports) + writer.write("import " + imp + ";" + NL); + + writer.write(NL); + writer.write(CLS_JAVADOC); + writer.write(NL); + writer.write("public class " + clsName + " implements " + interfaceName + "<" + simpleNameWithGeneric(type) + ">"); + } + + /** @return {@code format} formatted with {@code args}, prefixed with {@link #indent} tabs. */ + String indentedLine(String format, Object... args) { + SB sb = new SB(); + + for (int i = 0; i < indent; i++) + sb.a(TAB); + + sb.a(String.format(format, args)); + + return sb.toString(); + } + + /** @return simple name of {@code te} with {@code } wildcard type arguments appended when parameterised. */ + String simpleNameWithGeneric(TypeElement te) { + if (F.size(te.getTypeParameters()) == 0) + return te.getSimpleName().toString(); + + StringBuilder generic = new StringBuilder(te.getSimpleName() + "<"); + + for (int i = 0; i < F.size(te.getTypeParameters()); i++) { + if (i > 0) + generic.append(", "); + + generic.append("?"); + } + + generic.append(">"); + + return generic.toString(); + } + + /** */ + boolean assignableFrom(TypeMirror type, TypeMirror superType) { + return superType != null && env.getTypeUtils().isAssignable(type, superType); + } + + /** @return the {@link TypeMirror} for the fully-qualified {@code clazz}, or {@code null} if not on classpath. */ + TypeMirror type(String clazz) { + Elements elementUtils = env.getElementUtils(); + TypeElement typeElement = elementUtils.getTypeElement(clazz); + return typeElement != null ? typeElement.asType() : null; + } + + /** */ + TypeMirror erasedType(TypeMirror type) { + return env.getTypeUtils().erasure(type); + } + + /** @return {@code "msg."} accessor expression for {@code field}. */ + String fieldAccessor(VariableElement field) { + return "msg." + field.getSimpleName().toString(); + } + + /** Returns all fields declared directly on {@link #type}, in declaration order. */ + protected Map enclosedFields() { + Map result = new LinkedHashMap<>(); + + for (VariableElement f : ElementFilter.fieldsIn(type.getEnclosedElements())) + result.put(f.getSimpleName().toString(), f); + + return result; + } + + /** Appends {@code block} to {@code body}, inserting a blank-line separator when {@code body} is non-empty. */ + protected static void appendBlock(List body, List block) { + if (!body.isEmpty()) + body.add(EMPTY); + + body.addAll(block); + } + + /** @return {@code true} if a file with identical content is already generated (e.g. during incremental build). */ + public static boolean identicalFileIsAlreadyGenerated(ProcessingEnvironment env, String srcCode, String fqnClsName) { + try { + String fileName = fqnClsName.replace('.', '/') + ".java"; + FileObject prevFile = env.getFiler().getResource(StandardLocation.SOURCE_OUTPUT, "", fileName); + + String prevFileContent; + try (Reader r = prevFile.openReader(true)) { + prevFileContent = content(r); + } + + if (prevFileContent.contentEquals(srcCode)) + return true; + } + catch (Exception ignoredAttemptToGetExistingFile) { + // We have some other problem, not an existing file. + } + + return false; + } + + /** */ + static String content(Reader reader) throws IOException { + BufferedReader br = new BufferedReader(reader); + StringBuilder sb = new StringBuilder(); + String line; + + while ((line = br.readLine()) != null) + sb.append(line).append(NL); + + sb.deleteCharAt(sb.length() - 1); + + return sb.toString(); + } +} diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageMarshallerGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageMarshallerGenerator.java new file mode 100644 index 0000000000000..cb8c0c5d25d04 --- /dev/null +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageMarshallerGenerator.java @@ -0,0 +1,1066 @@ +/* + * 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; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BiFunction; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.QualifiedNameable; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.ArrayType; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.type.TypeVariable; +import javax.tools.Diagnostic; + +import static org.apache.ignite.internal.MessageProcessor.MARSHALLABLE_MESSAGE_INTERFACE; +import static org.apache.ignite.internal.MessageProcessor.MESSAGE_INTERFACE; + +/** + * Generates {@code *Marshaller} classes for {@link org.apache.ignite.plugin.extensions.communication.Message} + * types that are not {@link NonMarshallableMessage}. + */ +public class MessageMarshallerGenerator extends MessageGenerator { + /** Accumulated source lines for all generated marshal/unmarshal methods. */ + private final List marshall = new ArrayList<>(); + + /** */ + private final TypeMirror marshallableMsgType; + + /** */ + private final TypeMirror messageMirror; + + /** */ + private final TypeMirror cacheObjectMirror; + + /** */ + private final TypeMirror nonMarshallableMirror; + + /** */ + private final TypeMirror cacheIdAwareMirror; + + /** */ + private final TypeMirror cacheGroupIdMsgMirror; + + /** */ + private final TypeMirror mapMirror; + + /** */ + private final TypeMirror collectionMirror; + + /** */ + private boolean marshallable; + + /** */ + private boolean hasMarshalled; + + /** Enclosed fields of the currently processed type. Computed once per {@link #generateBody} call. */ + private Map enclosed; + + /** Nesting depth of the current marshal for-loop; names loop variables {@code e}, {@code e1}, {@code e2}… */ + private int loopDepth; + + /** */ + MessageMarshallerGenerator(ProcessingEnvironment env) { + super(env); + + marshallableMsgType = type(MARSHALLABLE_MESSAGE_INTERFACE); + messageMirror = type(MESSAGE_INTERFACE); + cacheObjectMirror = type("org.apache.ignite.internal.processors.cache.CacheObject"); + nonMarshallableMirror = type("org.apache.ignite.plugin.extensions.communication.NonMarshallableMessage"); + cacheIdAwareMirror = type("org.apache.ignite.plugin.extensions.communication.CacheIdAware"); + cacheGroupIdMsgMirror = type("org.apache.ignite.internal.processors.cache.GridCacheGroupIdMessage"); + mapMirror = type("java.util.Map"); + collectionMirror = type("java.util.Collection"); + } + + /** {@inheritDoc} */ + @Override String typeSuffix() { + return "Marshaller"; + } + + /** {@inheritDoc} */ + @Override boolean shouldSkip(TypeElement type) { + return isNonMarshallableMessage(type); + } + + /** {@inheritDoc} */ + @Override void generateBody(List fields) throws Exception { + enclosed = enclosedFields(); + marshallable = marshallableMsgType != null && assignableFrom(type.asType(), marshallableMsgType); + hasMarshalled = enclosed.values().stream().anyMatch(f -> + f.getAnnotation(Marshalled.class) != null || f.getAnnotation(MarshalledObjects.class) != null); + + indent = 1; + + generateMarshalMethod(fields); + generateUnmarshalMethods(fields); + } + + /** {@inheritDoc} */ + @Override String buildClassCode(String marshallerClsName) throws IOException { + try (Writer writer = new StringWriter()) { + imports.add(type.toString()); + imports.add("org.apache.ignite.plugin.extensions.communication.MessageMarshaller"); + + if (marshallable || hasMarshalled) + imports.add("org.apache.ignite.marshaller.Marshaller"); + + writeClassHeader(writer, "MessageMarshaller", marshallerClsName); + + writer.write(" {" + NL); + + writeConstructor(writer, marshallerClsName); + + for (String line : marshall) + writer.write(line + NL); + + writer.write("}"); + + return writer.toString(); + } + } + + /** Writes the constructor, including the {@code marshaller} field when needed. */ + private void writeConstructor(Writer writer, String marshallerClsName) throws IOException { + writer.write(indentedLine(METHOD_JAVADOC)); + writer.write(NL); + + if (marshallable || hasMarshalled) { + writer.write(indentedLine("private final Marshaller marshaller;")); + writer.write(NL + NL); + + writer.write(indentedLine(METHOD_JAVADOC)); + writer.write(NL); + writer.write(indentedLine("public " + marshallerClsName + "(Marshaller marshaller) {")); + writer.write(NL); + + indent++; + + writer.write(indentedLine("this.marshaller = marshaller;")); + writer.write(NL); + + indent--; + } + else { + writer.write(indentedLine("public " + marshallerClsName + "() {")); + writer.write(NL); + } + + writer.write(indentedLine("}")); + writer.write(NL + NL); + } + + /** Generates the {@code marshal} method body and appends it to {@link #marshall}. */ + private void generateMarshalMethod(List orderedFields) { + imports.add("org.apache.ignite.IgniteCheckedException"); + imports.add("org.apache.ignite.internal.GridKernalContext"); + imports.add("org.apache.ignite.internal.processors.cache.CacheObjectContext"); + + marshall.add(indentedLine(METHOD_JAVADOC)); + + marshall.add(indentedLine("@Override public void marshal(" + simpleNameWithGeneric(type) + + " msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException {")); + + indent++; + + List body = new ArrayList<>(); + + if (needsCtx(orderedFields)) + appendBlock(body, List.of(ctxResolutionLine())); + + appendMarshalledFieldsPrepare(body); + appendMarshalledPrepare(body); + + if (marshallable) + appendBlock(body, List.of(indentedLine("msg.marshal(marshaller);"))); + + appendFields(body, orderedFields, MarshalMode.PREPARE); + + marshall.addAll(body); + + indent--; + + marshall.add(indentedLine("}")); + } + + /** Generates all {@code unmarshal} overloads and appends them to {@link #marshall}. */ + private void generateUnmarshalMethods(List orderedFields) { + List nioFields = new ArrayList<>(); + List workerFields = new ArrayList<>(); + + for (VariableElement f : orderedFields) { + boolean nioField = isNioField(f); + + if (nioField && isMessage(f.asType())) + nioFields.add(f); + else { + if (nioField) + env.getMessager().printMessage(Diagnostic.Kind.ERROR, + "@NioField has no effect on non-Message field '" + f.getSimpleName() + "' of type " + f.asType(), f); + + workerFields.add(f); + } + } + + imports.add("org.apache.ignite.internal.util.typedef.internal.U"); + + String msgParam = simpleNameWithGeneric(type) + " msg, GridKernalContext kctx"; + + generateUnmarshalMethod("unmarshal", msgParam + ", CacheObjectContext nested, ClassLoader clsLdr", + workerFields, MarshalMode.FINISH_CACHE); + + generateUnmarshalMethod("unmarshal", msgParam, workerFields, MarshalMode.FINISH); + + if (!nioFields.isEmpty()) + generateUnmarshalNioMethod(msgParam, nioFields); + } + + /** Generates a single {@code unmarshal} overload for the given {@code mode}. */ + private void generateUnmarshalMethod(String methodName, String params, List fields, MarshalMode mode) { + marshall.add(EMPTY); + + marshall.add(indentedLine(METHOD_JAVADOC)); + + marshall.add(indentedLine("@Override public void " + methodName + "(" + params + ") throws IgniteCheckedException {")); + + indent++; + + List body = new ArrayList<>(); + + Set wireFieldSkip = mode == MarshalMode.FINISH_CACHE ? marshalledWireFieldsToSkip() : Set.of(); + + if (mode == MarshalMode.FINISH_CACHE && (needsCtx(fields) || !wireFieldSkip.isEmpty())) + appendBlock(body, List.of(ctxResolutionLine())); + + appendFields(body, fields, mode, wireFieldSkip); + + if (marshallable) { + if (mode == MarshalMode.FINISH_CACHE) + appendBlock(body, List.of(indentedLine("msg.unmarshal(marshaller, clsLdr);"))); + else + appendBlock(body, List.of(indentedLine("msg.unmarshal(marshaller, U.resolveClassLoader(kctx.config()));"))); + } + + appendMarshalledFinish(body, mode); + + if (mode == MarshalMode.FINISH_CACHE) { + appendMarshalledCollectionFinish(body); + appendMarshalledMapFinish(body); + appendMarshalledObjectsFinish(body); + } + + marshall.addAll(body); + + indent--; + + marshall.add(indentedLine("}")); + } + + /** Generates the {@code unmarshalNio} method for NIO-eligible {@code @Message} fields. */ + private void generateUnmarshalNioMethod(String params, List nioFields) { + marshall.add(EMPTY); + + marshall.add(indentedLine(METHOD_JAVADOC)); + + marshall.add(indentedLine("@Override public void unmarshalNio(" + params + ") throws IgniteCheckedException {")); + + indent++; + + List body = new ArrayList<>(); + + appendFields(body, nioFields, MarshalMode.FINISH); + + marshall.addAll(body); + + indent--; + + marshall.add(indentedLine("}")); + } + + /** Generates logical→wire conversions for all {@code @MarshalledCollection} and {@code @MarshalledMap} fields. */ + private void appendMarshalledFieldsPrepare(List body) { + for (VariableElement field : enclosed.values()) { + appendCollectionPrepare(body, field); + appendMapPrepare(body, field); + appendObjectsPrepare(body, field); + } + } + + /** Generates the {@code Collection} build-up for a {@code @MarshalledObjects} field in marshal. */ + private void appendObjectsPrepare(List body, VariableElement field) { + MarshalledObjects ann = field.getAnnotation(MarshalledObjects.class); + + if (ann == null) + return; + + String objField = "msg." + field.getSimpleName(); + String bytesField = "msg." + ann.value(); + + imports.add("java.util.ArrayList"); + + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null && %s == null) {", objField, bytesField)); + + indent++; + + code.add(indentedLine("%s = new ArrayList<>(%s.size());", bytesField, objField)); + code.add(EMPTY); + code.add(indentedLine("for (Object e : %s)", objField)); + + indent++; + + code.add(indentedLine("%s.add(U.marshal(marshaller, e));", bytesField)); + + indent--; + indent--; + + code.add(indentedLine("}")); + + appendBlock(body, code); + } + + /** Appends a {@code toArray} assignment for a {@code @MarshalledCollection} field, if present. */ + private void appendCollectionPrepare(List body, VariableElement field) { + MarshalledCollection ann = field.getAnnotation(MarshalledCollection.class); + + if (ann == null) + return; + + String colField = "msg." + field.getSimpleName(); + String arrField = "msg." + ann.value(); + String compName = arrayComponentName(requireEnclosed(enclosed, ann.value(), "@MarshalledCollection")); + + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null && %s == null)", colField, arrField)); + + indent++; + + code.add(indentedLine("%s = %s.toArray(new %s[0]);", arrField, colField, compName)); + + indent--; + + appendBlock(body, code); + } + + /** Appends key/value array assignments for a {@code @MarshalledMap} field, if present. */ + private void appendMapPrepare(List body, VariableElement field) { + MarshalledMap ann = field.getAnnotation(MarshalledMap.class); + + if (ann == null) + return; + + String mapField = "msg." + field.getSimpleName(); + String keysField = "msg." + ann.keys(); + String valuesField = "msg." + ann.values(); + VariableElement keysEl = requireEnclosed(enclosed, ann.keys(), "@MarshalledMap"); + + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null && %s == null) {", mapField, keysField)); + + indent++; + + code.addAll(keysEl.asType().getKind() == TypeKind.ARRAY + ? arrayMapBody(ann, mapField, keysField, keysEl, valuesField) + : viewBasedMapBody(keysField, mapField, valuesField)); + + indent--; + + code.add(indentedLine("}")); + + appendBlock(body, code); + } + + /** Generates {@code U.marshal} calls for all {@code @Marshalled} fields in marshal. */ + private void appendMarshalledPrepare(List body) { + forEachMarshalled((bytesAcc, objAcc) -> { + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null && %s == null)", objAcc, bytesAcc)); + + indent++; + + code.add(indentedLine("%s = U.marshal(marshaller, %s);", bytesAcc, objAcc)); + + indent--; + + return code; + }, body); + } + + /** Generates {@code U.unmarshal} calls for all {@code @Marshalled} fields in unmarshal. */ + private void appendMarshalledFinish(List body, MarshalMode mode) { + String clsLdr = mode == MarshalMode.FINISH_CACHE ? "clsLdr" : "U.resolveClassLoader(kctx.config())"; + + forEachMarshalled((bytesAcc, objAcc) -> { + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null)", bytesAcc)); + + indent++; + + code.add(indentedLine("%s = U.unmarshal(marshaller, %s, %s);", objAcc, bytesAcc, clsLdr)); + + indent--; + + return code; + }, body); + } + + /** Generates Set reconstruction for all {@code @MarshalledCollection} fields. */ + private void appendMarshalledCollectionFinish(List body) { + for (VariableElement field : enclosed.values()) { + MarshalledCollection colAnn = field.getAnnotation(MarshalledCollection.class); + + if (colAnn == null) + continue; + + String colField = "msg." + field.getSimpleName(); + String arrField = "msg." + colAnn.value(); + VariableElement wireField = requireEnclosed(enclosed, colAnn.value(), "@MarshalledCollection"); + + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null) {", arrField)); + + indent++; + + code.add(indentedLine("%s = U.newHashSet(%s.length);", colField, arrField)); + code.add(EMPTY); + code.addAll(collectionFinishForBlock(wireField, colField, arrField, field.getSimpleName().toString())); + code.add(EMPTY); + code.add(indentedLine("%s = null;", arrField)); + + indent--; + + code.add(indentedLine("}")); + + appendBlock(body, code); + } + } + + /** Generates Collection reconstruction for all {@code @MarshalledObjects} fields (cache-aware pass only). */ + private void appendMarshalledObjectsFinish(List body) { + for (VariableElement field : enclosed.values()) { + MarshalledObjects ann = field.getAnnotation(MarshalledObjects.class); + + if (ann == null) + continue; + + String objField = "msg." + field.getSimpleName(); + String bytesField = "msg." + ann.value(); + + imports.add("java.util.ArrayList"); + + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null) {", bytesField)); + + indent++; + + code.add(indentedLine("%s = new ArrayList<>(%s.size());", objField, bytesField)); + code.add(EMPTY); + code.add(indentedLine("for (byte[] e : %s)", bytesField)); + + indent++; + + code.add(indentedLine("%s.add(U.unmarshal(marshaller, e, clsLdr));", objField)); + + indent--; + + code.add(EMPTY); + code.add(indentedLine("%s = null;", bytesField)); + + indent--; + + code.add(indentedLine("}")); + + appendBlock(body, code); + } + } + + /** Generates the {@code for} loop body: per-element unmarshal + try/catch add into the collection. */ + private List collectionFinishForBlock(VariableElement wireField, String colField, String arrField, String fieldName) { + String compName = arrayComponentName(wireField); + TypeMirror compType = ((ArrayType)wireField.asType()).getComponentType(); + + List code = new ArrayList<>(); + + code.add(indentedLine("for (%s e : %s) {", compName, arrField)); + + indent++; + + code.addAll(codeFor(compType, "e", MarshalMode.FINISH_CACHE)); + code.add(EMPTY); + code.add(indentedLine("%s.add(e);", colField)); + + indent--; + + code.add(indentedLine("}")); + + return code; + } + + /** Returns names of wire fields skipped by {@link #appendFields} in FINISH_CACHE mode. */ + private Set marshalledWireFieldsToSkip() { + Set names = new HashSet<>(); + + for (VariableElement f : enclosed.values()) { + MarshalledCollection colAnn = f.getAnnotation(MarshalledCollection.class); + if (colAnn != null) + names.add(colAnn.value()); + + MarshalledMap mapAnn = f.getAnnotation(MarshalledMap.class); + if (mapAnn != null) { + names.add(mapAnn.keys()); + names.add(mapAnn.values()); + } + + MarshalledObjects objAnn = f.getAnnotation(MarshalledObjects.class); + if (objAnn != null) + names.add(objAnn.value()); + } + + return names; + } + + /** Generates Map reconstruction for all {@code @MarshalledMap} fields. */ + private void appendMarshalledMapFinish(List body) { + for (VariableElement field : enclosed.values()) { + MarshalledMap ann = field.getAnnotation(MarshalledMap.class); + + if (ann == null) + continue; + + VariableElement keysEl = requireEnclosed(enclosed, ann.keys(), "@MarshalledMap"); + VariableElement valsEl = requireEnclosed(enclosed, ann.values(), "@MarshalledMap"); + + String mapField = "msg." + field.getSimpleName(); + String keysField = "msg." + ann.keys(); + String valsField = "msg." + ann.values(); + + List code = keysEl.asType().getKind() == TypeKind.ARRAY + ? mapFinishArrayBlock(field, keysEl, valsEl, mapField, keysField, valsField) + : mapFinishCollectionBlock(field, keysEl, valsEl, mapField, keysField, valsField); + + appendBlock(body, code); + } + } + + /** Generates indexed-loop Map reconstruction for array-backed {@code @MarshalledMap} fields. */ + private List mapFinishArrayBlock(VariableElement field, VariableElement keysEl, VariableElement valsEl, String mapField, + String keysField, String valsField) { + boolean isFinal = field.getModifiers().contains(Modifier.FINAL); + String keyCompName = arrayComponentName(keysEl); + String valCompName = arrayComponentName(valsEl); + TypeMirror keyCompType = ((ArrayType)keysEl.asType()).getComponentType(); + TypeMirror valCompType = ((ArrayType)valsEl.asType()).getComponentType(); + + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null) {", keysField)); + + indent++; + + if (!isFinal) { + code.add(indentedLine("%s = U.newHashMap(%s.length);", mapField, keysField)); + code.add(EMPTY); + } + + code.add(indentedLine("for (int i = 0; i < %s.length; i++) {", keysField)); + + indent++; + + code.add(indentedLine("%s k = %s[i];", keyCompName, keysField)); + code.add(indentedLine("%s v = %s[i];", valCompName, valsField)); + + List keyUnmarshal = codeFor(keyCompType, "k", MarshalMode.FINISH_CACHE); + List valUnmarshal = codeFor(valCompType, "v", MarshalMode.FINISH_CACHE); + + if (!keyUnmarshal.isEmpty()) { + code.add(EMPTY); + code.addAll(keyUnmarshal); + } + + if (!valUnmarshal.isEmpty()) { + code.add(EMPTY); + code.addAll(valUnmarshal); + } + + code.add(EMPTY); + code.add(indentedLine("%s.put(k, v);", mapField)); + + indent--; + + code.add(indentedLine("}")); + code.add(EMPTY); + code.add(indentedLine("%s = null;", keysField)); + code.add(indentedLine("%s = null;", valsField)); + + indent--; + + code.add(indentedLine("}")); + + return code; + } + + /** Generates iterator-based Map reconstruction for collection-backed {@code @MarshalledMap} fields. */ + private List mapFinishCollectionBlock(VariableElement field, VariableElement keysEl, VariableElement valsEl, String mapField, + String keysField, String valsField) { + List keyArgs = ((DeclaredType)keysEl.asType()).getTypeArguments(); + List valArgs = ((DeclaredType)valsEl.asType()).getTypeArguments(); + + TypeMirror keyCompType = keyArgs.get(0); + TypeMirror valCompType = valArgs.get(0); + + Element keyElem = element(keyCompType); + Element valElem = element(valCompType); + + String keyCompName = keyElem.getSimpleName().toString(); + String valCompName = valElem.getSimpleName().toString(); + + imports.add(((QualifiedNameable)keyElem).getQualifiedName().toString()); + imports.add(((QualifiedNameable)valElem).getQualifiedName().toString()); + imports.add("java.util.Iterator"); + + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null) {", keysField)); + + indent++; + + code.add(indentedLine("%s = U.newHashMap(%s.size());", mapField, keysField)); + code.add(EMPTY); + code.add(indentedLine("Iterator<%s> keyIter = %s.iterator();", keyCompName, keysField)); + code.add(indentedLine("Iterator<%s> valIter = %s.iterator();", valCompName, valsField)); + code.add(EMPTY); + code.add(indentedLine("while (keyIter.hasNext()) {")); + + indent++; + + code.add(indentedLine("%s k = keyIter.next();", keyCompName)); + code.add(indentedLine("%s v = valIter.next();", valCompName)); + + List keyUnmarshal = codeFor(keyCompType, "k", MarshalMode.FINISH_CACHE); + List valUnmarshal = codeFor(valCompType, "v", MarshalMode.FINISH_CACHE); + + if (!keyUnmarshal.isEmpty()) { + code.add(EMPTY); + code.addAll(keyUnmarshal); + } + + if (!valUnmarshal.isEmpty()) { + code.add(EMPTY); + code.addAll(valUnmarshal); + } + + code.add(EMPTY); + code.add(indentedLine("%s.put(k, v);", mapField)); + + indent--; + + code.add(indentedLine("}")); + code.add(EMPTY); + code.add(indentedLine("%s = null;", keysField)); + code.add(indentedLine("%s = null;", valsField)); + + indent--; + + code.add(indentedLine("}")); + + return code; + } + + /** Generates key/value array population from the map's entry set. */ + private List arrayMapBody(MarshalledMap ann, String mapField, String keysField, VariableElement keysEl, String valuesField) { + String compName = arrayComponentName(keysEl); + String valCompName = arrayComponentName(requireEnclosed(enclosed, ann.values(), "@MarshalledMap")); + + List inner = new ArrayList<>(); + + imports.add("java.util.Map"); + + inner.add(indentedLine("%s = new %s[%s.size()];", keysField, compName, mapField)); + inner.add(indentedLine("%s = new %s[%s.length];", valuesField, valCompName, keysField)); + inner.add(indentedLine("int i = 0;")); + inner.add(indentedLine("for (Map.Entry e : %s.entrySet()) {", mapField)); + + indent++; + + inner.add(indentedLine("%s[i] = (%s)e.getKey();", keysField, compName)); + inner.add(indentedLine("%s[i] = (%s)e.getValue();", valuesField, valCompName)); + inner.add(indentedLine("i++;")); + + indent--; + + inner.add(indentedLine("}")); + + return inner; + } + + /** Generates key/value assignments backed by the map's own {@code keySet()} and {@code values()} views. */ + private List viewBasedMapBody(String keysField, String mapField, String valuesField) { + List inner = new ArrayList<>(); + + inner.add(indentedLine("%s = %s.keySet();", keysField, mapField)); + inner.add(indentedLine("%s = %s.values();", valuesField, mapField)); + + return inner; + } + + /** Marshals each field and appends non-empty results to {@code body}. */ + private void appendFields(List body, List fields, MarshalMode mode) { + appendFields(body, fields, mode, Set.of()); + } + + /** Marshals each field, skipping names in {@code skip}, and appends non-empty results to {@code body}. */ + private void appendFields(List body, List fields, MarshalMode mode, Set skip) { + for (VariableElement field : fields) { + if (skip.contains(field.getSimpleName().toString())) + continue; + + List result = codeFor(field.asType(), fieldAccessor(field), mode); + + if (!result.isEmpty()) + appendBlock(body, result); + } + } + + /** Returns generated marshal/unmarshal code lines for field of type {@code t}, or empty if none needed. */ + private List codeFor(TypeMirror t, String accessor, MarshalMode mode) { + if (t.getKind() == TypeKind.ARRAY) { + TypeMirror comp = ((ArrayType)t).getComponentType(); + + return comp.getKind() == TypeKind.DECLARED ? marshallArray(comp, accessor, mode) : List.of(); + } + + if (t.getKind() == TypeKind.DECLARED || t.getKind() == TypeKind.TYPEVAR) { + if (isMessage(t)) + return marshallMessage(accessor, mode); + if (isCacheObject(t)) + return marshallCacheObject(accessor, mode); + if (isMap(t)) + return marshallMap((DeclaredType)t, accessor, mode); + if (isCollection(t)) + return marshallCollection((DeclaredType)t, accessor, mode); + } + + return List.of(); + } + + /** Generates a null-guarded {@code MessageMarshaller.marshal/unmarshal} call. */ + private List marshallMessage(String accessor, MarshalMode mode) { + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null)", accessor)); + + indent++; + + switch (mode) { + case PREPARE: + code.add(indentedLine("MessageMarshaller.marshal(kctx.messageFactory(), %s, kctx, ctx);", accessor)); + break; + case FINISH: + code.add(indentedLine("MessageMarshaller.unmarshal(kctx.messageFactory(), %s, kctx);", accessor)); + break; + case FINISH_CACHE: + code.add(indentedLine("MessageMarshaller.unmarshal(kctx.messageFactory(), %s, kctx, ctx, clsLdr);", accessor)); + break; + } + + indent--; + + return code; + } + + /** Generates a null-and-ctx-guarded {@code marshal/unmarshal} call on a {@code CacheObject}. */ + private List marshallCacheObject(String accessor, MarshalMode mode) { + if (mode == MarshalMode.FINISH) + return List.of(); + + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null && ctx != null)", accessor)); + + indent++; + + code.add(mode == MarshalMode.PREPARE + ? indentedLine("%s.marshal(ctx);", accessor) + : indentedLine("%s.unmarshal(ctx, clsLdr);", accessor)); + + indent--; + + return code; + } + + /** Generates a null-guarded for-each loop over the array's elements. */ + private List marshallArray(TypeMirror comp, String accessor, MarshalMode mode) { + Element elem = ((DeclaredType)comp).asElement(); + + imports.add(((QualifiedNameable)elem).getQualifiedName().toString()); + + indent++; + + List loopCode = forLoop(elem.getSimpleName().toString(), comp, accessor, mode); + + indent--; + + return wrapNullGuarded(accessor, loopCode); + } + + /** Generates a null-guarded for-each loop over the collection's elements. */ + private List marshallCollection(DeclaredType t, String accessor, MarshalMode mode) { + TypeMirror arg = t.getTypeArguments().get(0); + + if (arg.getKind() != TypeKind.DECLARED && arg.getKind() != TypeKind.TYPEVAR) + return List.of(); + + Element elem = element(arg); + + imports.add(((QualifiedNameable)elem).getQualifiedName().toString()); + imports.add("java.util.Collection"); + + String typeName = elem.getSimpleName().toString(); + + indent++; + + List loopCode = forLoop(typeName, arg, "(Collection)" + accessor, mode); + + indent--; + + return wrapNullGuarded(accessor, loopCode); + } + + /** Iterates {@code keySet()} then {@code values()}, wrapping both loops in a null-guard. */ + private List marshallMap(DeclaredType t, String accessor, MarshalMode mode) { + List args = t.getTypeArguments(); + + indent++; + + List combined = new ArrayList<>(); + + for (int i = 0; i < 2; i++) { + TypeMirror elemType = args.get(i); + + if (elemType.getKind() != TypeKind.DECLARED && elemType.getKind() != TypeKind.TYPEVAR) + continue; + + Element elem = element(elemType); + + imports.add(((QualifiedNameable)elem).getQualifiedName().toString()); + imports.add("java.util.Collection"); + + String typeName = elem.getSimpleName().toString(); + String collection = i == 0 ? "keySet" : "values"; + String iterable = "((Collection)" + accessor + "." + collection + "())"; + + combined.addAll(forLoop(typeName, elemType, iterable, mode)); + } + + indent--; + + return wrapNullGuarded(accessor, combined); + } + + /** Returns empty if {@code elemType} requires no marshalling; otherwise returns a for-each loop over {@code iterable}. */ + private List forLoop(String typeName, TypeMirror elemType, String iterable, MarshalMode mode) { + String el = loopDepth == 0 ? "e" : "e" + loopDepth; + + loopDepth++; + indent++; + + List inner = codeFor(elemType, el, mode); + + indent--; + loopDepth--; + + if (inner.isEmpty()) + return List.of(); + + List code = new ArrayList<>(); + + code.add(indentedLine("for (%s %s : %s) {", typeName, el, iterable)); + + code.addAll(inner); + + code.add(indentedLine("}")); + + return code; + } + + /** Returns empty if {@code inner} is empty; otherwise wraps {@code inner} in a null-guard on {@code nullGuard}. */ + private List wrapNullGuarded(String nullGuard, List inner) { + if (inner.isEmpty()) + return List.of(); + + List code = new ArrayList<>(); + + code.add(indentedLine("if (%s != null) {", nullGuard)); + + code.addAll(inner); + + code.add(indentedLine("}")); + + return code; + } + + /** + * Returns the {@code CacheObjectContext ctx} resolution line for the current message type. Cache messages resolve + * via the cache, group messages via the cache group — the group's context outlives the stop of individual caches, + * so cache objects still unmarshal while a cache (group) is being destroyed. + */ + private String ctxResolutionLine() { + if (isCacheIdAwareMessage(type)) + return indentedLine("CacheObjectContext ctx = nested != null ? nested : " + + "kctx.cache().context().cacheObjectContext(msg.cacheId());"); + else if (isCacheGroupIdMessage(type)) + return indentedLine("CacheObjectContext ctx = nested != null ? nested : " + + "kctx.cache().cacheGroup(msg.groupId()) == null ? null : " + + "kctx.cache().cacheGroup(msg.groupId()).cacheObjectContext();"); + else + return indentedLine("CacheObjectContext ctx = nested;"); + } + + /** Returns {@code true} if any field requires {@code ctx} in generated marshal/unmarshal code. */ + private boolean needsCtx(List fields) { + return fields.stream().anyMatch(f -> needsCtxType(f.asType())); + } + + /** Returns {@code true} if type {@code t} (or its element/key/value types) requires {@code ctx}. */ + private boolean needsCtxType(TypeMirror t) { + if (t.getKind() == TypeKind.ARRAY) + return needsCtxType(((ArrayType)t).getComponentType()); + + if (t.getKind() == TypeKind.DECLARED || t.getKind() == TypeKind.TYPEVAR) { + if (isMessage(t) || isCacheObject(t)) + return true; + + if (isMap(t)) { + List args = ((DeclaredType)t).getTypeArguments(); + return needsCtxType(args.get(0)) || needsCtxType(args.get(1)); + } + + if (isCollection(t)) { + List args = ((DeclaredType)t).getTypeArguments(); + return needsCtxType(args.get(0)); + } + } + + return false; + } + + /** */ + private boolean isMessage(TypeMirror type) { + return assignableFrom(type, messageMirror); + } + + /** */ + private boolean isCacheObject(TypeMirror type) { + return assignableFrom(type, cacheObjectMirror); + } + + /** Returns {@code true} if {@code type} (erased) is assignable to {@code java.util.Map}. */ + private boolean isMap(TypeMirror type) { + return assignableFrom(erasedType(type), mapMirror); + } + + /** Returns {@code true} if {@code type} (erased) is assignable to {@code java.util.Collection}. */ + private boolean isCollection(TypeMirror type) { + return assignableFrom(erasedType(type), collectionMirror); + } + + /** */ + private boolean isNonMarshallableMessage(TypeElement te) { + return assignableFrom(te.asType(), nonMarshallableMirror); + } + + /** */ + private boolean isCacheIdAwareMessage(TypeElement te) { + return assignableFrom(te.asType(), cacheIdAwareMirror); + } + + /** */ + private boolean isCacheGroupIdMessage(TypeElement te) { + return assignableFrom(te.asType(), cacheGroupIdMsgMirror); + } + + /** */ + private static boolean isNioField(VariableElement field) { + return field.getAnnotation(NioField.class) != null; + } + + /** Returns the enclosed field named {@code name}, or throws if absent. */ + private VariableElement requireEnclosed(Map enclosed, String name, String annotationName) { + VariableElement el = enclosed.get(name); + + if (el == null) + throw new IllegalStateException(annotationName + " companion field '" + name + "' not found in " + type); + + return el; + } + + /** Iterates all {@code @Marshalled} fields and applies {@code codeGen(bytesAccessor, objAccessor)} to each. */ + private void forEachMarshalled(BiFunction> codeGen, List body) { + for (VariableElement field : enclosed.values()) { + Marshalled ann = field.getAnnotation(Marshalled.class); + + if (ann == null) + continue; + + appendBlock(body, codeGen.apply("msg." + ann.value(), "msg." + field.getSimpleName())); + } + } + + /** Returns the element for {@code t}; for a type variable, uses its upper bound. */ + private Element element(TypeMirror t) { + return t.getKind() == TypeKind.DECLARED ? + ((DeclaredType)t).asElement() : + ((DeclaredType)((TypeVariable)t).getUpperBound()).asElement(); + } + + /** Returns the simple name of the array component type of {@code field}. */ + private static String arrayComponentName(VariableElement field) { + return ((DeclaredType)((ArrayType)field.asType()).getComponentType()).asElement().getSimpleName().toString(); + } + + /** Marshal mode controls which overload is being generated. */ + private enum MarshalMode { + /** */ + PREPARE, + + /** Lightweight unmarshal. Messages only, CacheObject fields are skipped (no cache context available). */ + FINISH, + + /** Unmarshal with full cache context and class loader. */ + FINISH_CACHE + } +} diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java index d6d331175e8c4..4c648db0aff3e 100644 --- a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java @@ -75,7 +75,7 @@ public class MessageProcessor extends AbstractProcessor { static final String COMPRESSED_MESSAGE_CLASS = "org.apache.ignite.internal.managers.communication.CompressedMessage"; /** Externalizable message. */ - static final String MARSHALLABLE_MESSAGE_INTERFACE = "org.apache.ignite.internal.MarshallableMessage"; + static final String MARSHALLABLE_MESSAGE_INTERFACE = "org.apache.ignite.plugin.extensions.communication.MarshallableMessage"; /** */ public static final String GRID_H2_NULL = "org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2Null"; @@ -97,17 +97,25 @@ public class MessageProcessor extends AbstractProcessor { static final String[] SKIP_MESSAGES = { "org.apache.ignite.internal.processors.odbc.ClientMessage", COMPRESSED_MESSAGE_CLASS, - "org.apache.ignite.loadtests.communication.GridTestMessage" + "org.apache.ignite.loadtests.communication.GridTestMessage", + "org.apache.ignite.spi.communication.tcp.TestDelayMessage" }; /** */ private final Map> enumMappersInUse = new HashMap<>(); - /** - * Processes all classes implementing the {@code Message} interface and generates corresponding serializer code. - */ + /** Processes all classes implementing the {@code Message} interface and generates corresponding serializer code. */ @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - TypeMirror msgType = processingEnv.getElementUtils().getTypeElement(MESSAGE_INTERFACE).asType(); + TypeElement msgEl = processingEnv.getElementUtils().getTypeElement(MESSAGE_INTERFACE); + + if (msgEl == null) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, + "Cannot resolve " + MESSAGE_INTERFACE + " on the annotation-processing classpath."); + + return false; + } + + TypeMirror msgType = msgEl.asType(); List emptyMsgs = typesToTypeMirrors(EMPTY_MESSAGES); List skipMsgs = typesToTypeMirrors(SKIP_MESSAGES); @@ -155,6 +163,22 @@ public class MessageProcessor extends AbstractProcessor { "Failed to generate a message serializer:" + e.getMessage(), type.getKey()); } + + try { + new MessageMarshallerGenerator(processingEnv).generate(type.getKey(), type.getValue()); + } + catch (Exception e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, + "Failed to generate a message marshaller:" + e.getMessage(), type.getKey()); + } + + try { + new MessageDeploymentGenerator(processingEnv).generate(type.getKey(), type.getValue()); + } + catch (Exception e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, + "Failed to generate a message deployer:" + e.getMessage(), type.getKey()); + } } return true; @@ -192,7 +216,7 @@ private boolean checkConstructors(TypeElement clazz) { * The resulting list is sorted in ascending order of the {@code @Order} value. * * @param type the {@code TypeElement} representing the class to inspect. - * @return a list of {@code VariableElement} objects representing all ordered fields, including those declared in superclasses. + * @return all ordered fields including those in superclasses, sorted by ascending {@code @Order} value. */ private List orderedFields(TypeElement type) { List> hierList = hierarchicalOrderedFields(type); @@ -246,7 +270,7 @@ private List> hierarchicalOrderedFields(TypeElement type) } /** - * Validates consistency of enum field mappers configuration: the same mapper is used for the same enum in different messages, + * Validates consistency of enum field mappers configuration: the same mapper is used for the same enum across different messages, * CustomMapper annotation is used only for enum fields. * * @param type Type implementing Message interface. diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java index 052db3afcdf62..3012b08922cd7 100644 --- a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageSerializerGenerator.java @@ -17,12 +17,7 @@ package org.apache.ignite.internal; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.Reader; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; @@ -32,57 +27,26 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.TreeSet; import java.util.UUID; -import javax.annotation.processing.FilerException; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.QualifiedNameable; -import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.ArrayType; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.PrimitiveType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import javax.tools.Diagnostic; -import javax.tools.FileObject; -import javax.tools.JavaFileObject; -import javax.tools.StandardLocation; import org.apache.ignite.internal.systemview.SystemViewRowAttributeWalkerProcessor; import org.apache.ignite.internal.util.typedef.internal.SB; import org.jetbrains.annotations.Nullable; import static org.apache.ignite.internal.MessageProcessor.COMPRESSED_MESSAGE_CLASS; -import static org.apache.ignite.internal.MessageProcessor.MARSHALLABLE_MESSAGE_INTERFACE; import static org.apache.ignite.internal.MessageProcessor.MESSAGE_INTERFACE; -/** - * Generates serializer class for given {@code Message} class. The generated serializer follows the naming convention: - * {@code org.apache.ignite.internal.codegen.[MessageClassName]Serializer}. - */ -public class MessageSerializerGenerator { - /** */ - private static final String EMPTY = ""; - - /** */ - public static final String TAB = " "; - - /** */ - public static final String NL = System.lineSeparator(); - - /** */ - private static final String CLS_JAVADOC = "/** " + NL + - " * This class is generated automatically." + NL + - " *" + NL + - " * @see org.apache.ignite.internal.MessageProcessor" + NL + - " */"; - - /** */ - public static final String METHOD_JAVADOC = "/** */"; - +/** Generates {@code *Serializer} classes for {@link org.apache.ignite.plugin.extensions.communication.Message} types. */ +public class MessageSerializerGenerator extends MessageGenerator { /** */ private static final String RETURN_FALSE_STMT = "return false;"; @@ -93,97 +57,54 @@ public class MessageSerializerGenerator { private static final String COMPRESSED_MSG_ERROR = "CompressedMessage should not be used explicitly. " + "To compress the required field use the @Compress annotation."; - /** Collection of lines for {@code writeTo} method. */ + /** */ private final List write = new ArrayList<>(); - /** Collection of lines for {@code readFrom} method. */ - private final List read = new ArrayList<>(); - - /** Collection of message-specific imports. */ - private final Set imports = new TreeSet<>(); - - /** Collection of Serializer class fields containing mappers for message enum fields. */ - private final Set fields = new TreeSet<>(); - /** */ - private final ProcessingEnvironment env; - - /** Stored type of the message being processed. */ - private TypeElement type; + private final List read = new ArrayList<>(); - /** The marshallable message type. */ - private final TypeMirror marshallableMsgType; - - /** */ - private int indent; + /** Enum-mapper field declarations emitted at the top of the generated {@code *Serializer} class. */ + private final Set fields = new java.util.TreeSet<>(); /** */ MessageSerializerGenerator(ProcessingEnvironment env) { - this.env = env; - - marshallableMsgType = env.getElementUtils().getTypeElement(MARSHALLABLE_MESSAGE_INTERFACE).asType(); + super(env); } - /** */ - void generate(TypeElement type, List fields) throws Exception { - assert this.type == null : "Message serializer generator isn't stateless and is supposed to be single-use."; - - this.type = type; + /** {@inheritDoc} */ + @Override String typeSuffix() { + return "Serializer"; + } + /** {@inheritDoc} */ + @Override void generateBody(List fields) throws Exception { generateMethods(fields); + // Include superclass types in imports so generated code can cast to them for inherited fields. SystemViewRowAttributeWalkerProcessor.superclasses(env, type).forEach(el -> imports.add(el.toString())); - - String serClsName = type.getSimpleName() + (marshallableMessage() ? "Marshallable" : "") + "Serializer"; - String serFqnClsName = env.getElementUtils().getPackageOf(type) + "." + serClsName; - String serCode = generateSerializerCode(serClsName); - - try { - JavaFileObject file = env.getFiler().createSourceFile(serFqnClsName); - - try (Writer writer = file.openWriter()) { - writer.append(serCode); - writer.flush(); - } - } - catch (FilerException e) { - // IntelliJ IDEA parses Ignite's pom.xml and configures itself to use this annotation processor on each Run. - // During a Run, it invokes the processor and may fail when attempting to generate sources that already exist. - // There is no a setting to disable this invocation. The IntelliJ community suggests a workaround — delegating - // all Run commands to Maven. However, this significantly slows down test startup time. - // This hack checks whether the content of a generating file is identical to already existed file, and skips - // handling this class if it is. - if (!identicalFileIsAlreadyGenerated(env, serCode, serFqnClsName)) { - env.getMessager().printMessage( - Diagnostic.Kind.ERROR, - "MessageSerializer " + serClsName + " is already generated. Try 'mvn clean install' to fix the issue."); - - throw e; - } - } } - /** Generates full code for a serializer class. */ - private String generateSerializerCode(String serClsName) throws IOException { - if (marshallableMessage()) { - fields.add("private final Marshaller marshaller;"); - fields.add("private final ClassLoader clsLdr;"); - } - + /** {@inheritDoc} */ + @Override String buildClassCode(String serClsName) throws IOException { try (Writer writer = new StringWriter()) { - writeClassHeader(writer, env.getElementUtils().getPackageOf(type).toString(), serClsName); + imports.add(type.toString()); + imports.add("org.apache.ignite.plugin.extensions.communication.MessageSerializer"); + imports.add("org.apache.ignite.plugin.extensions.communication.MessageWriter"); + imports.add("org.apache.ignite.plugin.extensions.communication.MessageReader"); + + writeClassHeader(writer, "MessageSerializer", serClsName); + + writer.write(" {" + NL); writeClassFields(writer); writeConstructor(writer, serClsName); - // Write #writeTo method. for (String w: write) writer.write(w + NL); writer.write(TAB + "}" + NL + NL); - // Write #readFrom method. for (String r: read) writer.write(r + NL); @@ -191,36 +112,20 @@ private String generateSerializerCode(String serClsName) throws IOException { writer.write("}"); - writer.write(NL); - return writer.toString(); } } /** */ private void writeConstructor(Writer writer, String serClsName) throws IOException { - if (!marshallableMessage()) - return; - ++indent; - writer.write(identedLine(METHOD_JAVADOC)); + writer.write(indentedLine(METHOD_JAVADOC)); writer.write(NL); - writer.write(identedLine("public " + serClsName + "(Marshaller marshaller, ClassLoader clsLdr) {")); - + writer.write(indentedLine("public " + serClsName + "() {")); writer.write(NL); - - ++indent; - - writer.write(identedLine("this.marshaller = marshaller;")); - writer.write(NL); - writer.write(identedLine("this.clsLdr = clsLdr;")); - - --indent; - + writer.write(indentedLine("}")); writer.write(NL); - - writer.write(identedLine("}")); writer.write(NL); --indent; @@ -240,8 +145,8 @@ private void generateMethods(List fields) throws Exception { indent--; - finish(write, false, false); - finish(read, true, marshallableMessage()); + finish(write); + finish(read); } /** @@ -262,57 +167,30 @@ private void generateMethods(List fields) throws Exception { private void start(Collection code, boolean write) { indent = 1; - code.add(identedLine(METHOD_JAVADOC)); + code.add(indentedLine(METHOD_JAVADOC)); - code.add(identedLine("@Override public boolean %s(" + type.getSimpleName() + " msg, %s) {", - write ? "writeTo" : "readFrom", - write ? "MessageWriter writer" : "MessageReader reader")); + code.add(indentedLine("@Override public boolean %s(" + simpleNameWithGeneric(type) + " msg, %s) {", + write ? "writeTo" : "readFrom", write ? "MessageWriter writer" : "MessageReader reader")); indent++; if (write) { - code.add(identedLine("if (!writer.isHeaderWritten()) {")); + code.add(indentedLine("if (!writer.isHeaderWritten()) {")); indent++; returnFalseIfWriteFailed(code, "writer.writeHeader", "directType()"); - if (write && marshallableMessage()) { - imports.add("org.apache.ignite.IgniteCheckedException"); - imports.add("org.apache.ignite.IgniteException"); - - code.add(EMPTY); - - code.add(identedLine("try {")); - - indent++; - - code.add(identedLine("msg.prepareMarshal(marshaller);")); - - indent--; - - code.add(identedLine("}")); - code.add(identedLine("catch (IgniteCheckedException e) {")); - - indent++; - - code.add(identedLine("throw new IgniteException(\"Failed to marshal object \" + msg.getClass().getSimpleName(), e);")); - - indent--; - - code.add(identedLine("}")); - } - code.add(EMPTY); - code.add(identedLine("writer.onHeaderWritten();")); + code.add(indentedLine("writer.onHeaderWritten();")); indent--; - code.add(identedLine("}")); + code.add(indentedLine("}")); code.add(EMPTY); } - code.add(identedLine("switch (%s.state()) {", write ? "writer" : "reader")); + code.add(indentedLine("switch (%s.state()) {", write ? "writer" : "reader")); } /** @@ -341,14 +219,14 @@ private void processField(VariableElement field, int opt) throws Exception { * @param opt Case option. */ private void writeField(VariableElement field, int opt) throws Exception { - write.add(identedLine("case %d:", opt)); + write.add(indentedLine("case %d:", opt)); indent++; returnFalseIfWriteFailed(field); write.add(EMPTY); - write.add(identedLine("writer.incrementState();")); + write.add(indentedLine("writer.incrementState();")); write.add(EMPTY); indent--; @@ -369,24 +247,20 @@ private void writeField(VariableElement field, int opt) throws Exception { * @param opt Case option. */ private void readField(VariableElement field, int opt) throws Exception { - read.add(identedLine("case %d:", opt)); + read.add(indentedLine("case %d:", opt)); indent++; returnFalseIfReadFailed(field); read.add(EMPTY); - read.add(identedLine("reader.incrementState();")); + read.add(indentedLine("reader.incrementState();")); read.add(EMPTY); indent--; } - /** - * Discover access write methods, like {@code writeInt}. - * - * @param field Field to generate write code. - */ + /** Appends a write-fail guard for {@code field}, emitting {@code return false;} when the write fails. */ private void returnFalseIfWriteFailed(VariableElement field) throws Exception { String getExpr = field.getSimpleName().toString(); @@ -531,48 +405,38 @@ private String typeNameToFieldName(String typeName) { return new String(typeNameChars); } - /** - * Generate code of writing header. - *

-     * if (!writer.writeHeader(msg.directType()))
-     *     return false;
-     * 
- */ + /** Appends an accessor-based write-fail guard, emitting {@code return false;} when the write fails. */ private void returnFalseIfWriteFailed(Collection code, String accessor, @Nullable String... args) { String argsStr = String.join(", ", args); - code.add(identedLine("if (!%s(msg.%s))", accessor, argsStr)); + code.add(indentedLine("if (!%s(msg.%s))", accessor, argsStr)); indent++; - code.add(identedLine(RETURN_FALSE_STMT)); + code.add(indentedLine(RETURN_FALSE_STMT)); indent--; } - /** - * Generate code of writing single field: - */ + /** Appends a field-based write-fail guard, casting to the declaring class for inherited fields. */ private void returnFalseIfWriteFailed(Collection code, VariableElement field, String accessor, @Nullable String... args) { String argsStr = String.join(", ", args); if (type.equals(field.getEnclosingElement())) - code.add(identedLine("if (!%s(msg.%s))", accessor, argsStr)); + code.add(indentedLine("if (!%s(msg.%s))", accessor, argsStr)); else { // Field has to be requested from a super class object. - code.add(identedLine("if (!%s(((%s)msg).%s))", accessor, field.getEnclosingElement().getSimpleName(), argsStr)); + code.add(indentedLine("if (!%s(((%s)msg).%s))", accessor, field.getEnclosingElement().getSimpleName(), argsStr)); } indent++; - code.add(identedLine(RETURN_FALSE_STMT)); + code.add(indentedLine(RETURN_FALSE_STMT)); indent--; } - /** - * Generate code of writing single enum field mapped with EnumMapper: - */ + /** Appends an enum write-fail guard using the mapper call to convert the field value before writing. */ private void returnFalseIfEnumWriteFailed( Collection code, VariableElement field, @@ -580,25 +444,21 @@ private void returnFalseIfEnumWriteFailed( String mapperCall, String fieldGetterCall) { if (type.equals(field.getEnclosingElement())) - code.add(identedLine("if (!%s(%s(msg.%s)))", writerCall, mapperCall, fieldGetterCall)); + code.add(indentedLine("if (!%s(%s(msg.%s)))", writerCall, mapperCall, fieldGetterCall)); else { // Field has to be requested from a super class object. - code.add(identedLine("if (!%s(%s(((%s)msg).%s)))", + code.add(indentedLine("if (!%s(%s(((%s)msg).%s)))", writerCall, mapperCall, field.getEnclosingElement().getSimpleName(), fieldGetterCall)); } indent++; - code.add(identedLine(RETURN_FALSE_STMT)); + code.add(indentedLine(RETURN_FALSE_STMT)); indent--; } - /** - * Discover access read methods, like {@code readInt}. - * - * @param field Field. - */ + /** Appends a read-fail guard for {@code field}, returning {@code false} when reading is incomplete. */ private void returnFalseIfReadFailed(VariableElement field) throws Exception { TypeMirror type = field.asType(); @@ -876,39 +736,30 @@ private PrimitiveType unboxedType(TypeMirror type) { } } - /** - * Generate code of reading single field. - * - * @param field Field. - * @param mtd Method name. - */ + /** Appends a read-fail guard using {@code mtd} to read and assign {@code field}, casting for inherited fields. */ private void returnFalseIfReadFailed(VariableElement field, String mtd, String... args) { String argsStr = String.join(", ", args); if (type.equals(field.getEnclosingElement())) - read.add(identedLine("msg.%s = %s(%s);", field.getSimpleName().toString(), mtd, argsStr)); + read.add(indentedLine("msg.%s = %s(%s);", field.getSimpleName().toString(), mtd, argsStr)); else { // Field has to be requested from a super class object. - read.add(identedLine("((%s)msg).%s = %s(%s);", + read.add(indentedLine("((%s)msg).%s = %s(%s);", field.getEnclosingElement().getSimpleName(), field.getSimpleName().toString(), mtd, argsStr)); } read.add(EMPTY); - read.add(identedLine("if (!reader.isLastRead())")); + read.add(indentedLine("if (!reader.isLastRead())")); indent++; - read.add(identedLine(RETURN_FALSE_STMT)); + read.add(indentedLine(RETURN_FALSE_STMT)); indent--; } - /** - * Generate code of reading single field: - * - * @param mapperDecodeCallStmnt Method name. - */ + /** Appends an enum read-fail guard using the mapper decode call to set {@code field}. */ private void returnFalseIfEnumReadFailed(VariableElement field, String mapperDecodeCallStmnt, String enumValuesFieldName) { String readOp; @@ -918,84 +769,38 @@ private void returnFalseIfEnumReadFailed(VariableElement field, String mapperDec readOp = line("%s(%s, reader.readByte())", mapperDecodeCallStmnt, enumValuesFieldName); if (type.equals(field.getEnclosingElement())) - read.add(identedLine("msg.%s = %s;", field.getSimpleName().toString(), readOp)); + read.add(indentedLine("msg.%s = %s;", field.getSimpleName().toString(), readOp)); else { // Field has to be requested from a super class object. - read.add(identedLine("((%s)msg).%s = %s;", + read.add(indentedLine("((%s)msg).%s = %s;", field.getEnclosingElement().getSimpleName(), field.getSimpleName().toString(), readOp)); } read.add(EMPTY); - read.add(identedLine("if (!reader.isLastRead())")); + read.add(indentedLine("if (!reader.isLastRead())")); indent++; - read.add(identedLine(RETURN_FALSE_STMT)); + read.add(indentedLine(RETURN_FALSE_STMT)); indent--; } - /** */ - private void finish(List code, boolean read, boolean marshallable) { + /** Closes the write/read method with a final {@code return true;} statement. */ + private void finish(List code) { String lastLine = code.get(code.size() - 1); if (EMPTY.equals(lastLine)) code.remove(code.size() - 1); - code.add(identedLine("}")); + code.add(indentedLine("}")); code.add(EMPTY); - if (read && marshallable) { - imports.add("org.apache.ignite.IgniteCheckedException"); - imports.add("org.apache.ignite.IgniteException"); - - code.add(identedLine("try {")); - - indent++; - - code.add(identedLine("msg.finishUnmarshal(marshaller, clsLdr);")); - - indent--; - - code.add(identedLine("}")); - code.add(identedLine("catch (IgniteCheckedException e) {")); - - indent++; - - code.add(identedLine("throw new IgniteException(\"Failed to unmarshal object \" + msg.getClass().getSimpleName(), e);")); - - indent--; - - code.add(identedLine("}")); - - code.add(EMPTY); - } - - code.add(identedLine("return true;")); - } - - /** - * Creates line with current indent from given arguments. - * - * @return Line with current indent. - */ - private String identedLine(String format, Object... args) { - SB sb = new SB(); - - for (int i = 0; i < indent; i++) - sb.a(TAB); - - sb.a(String.format(format, args)); - - return sb.toString(); + code.add(indentedLine("return true;")); } - /** - * Creates line from given arguments. - * - * @return Line. - */ + /** @return {@code format} with {@code args} applied, without indentation. */ private String line(String format, Object... args) { SB sb = new SB(); @@ -1012,9 +817,9 @@ private void writeClassFields(Writer writer) throws IOException { indent = 1; for (String field: fields) { - writer.write(identedLine(METHOD_JAVADOC)); + writer.write(indentedLine(METHOD_JAVADOC)); writer.write(NL); - writer.write(identedLine(field)); + writer.write(indentedLine(field)); writer.write(NL); } writer.write(NL); @@ -1022,46 +827,6 @@ private void writeClassFields(Writer writer) throws IOException { indent = 0; } - /** Write header of serializer class: license, imports, class declaration. */ - private void writeClassHeader(Writer writer, String pkgName, String serClsName) throws IOException { - try (InputStream in = getClass().getClassLoader().getResourceAsStream("license.txt"); - BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { - - PrintWriter out = new PrintWriter(writer); - - String line; - - while ((line = reader.readLine()) != null) - out.println(line); - } - - writer.write(NL); - writer.write("package " + pkgName + ";" + NL + NL); - - imports.add(type.toString()); - - if (marshallableMessage()) - imports.add("org.apache.ignite.marshaller.Marshaller"); - - imports.add("org.apache.ignite.plugin.extensions.communication.MessageSerializer"); - imports.add("org.apache.ignite.plugin.extensions.communication.MessageWriter"); - imports.add("org.apache.ignite.plugin.extensions.communication.MessageReader"); - - for (String regularImport : imports) - writer.write("import " + regularImport + ";" + NL); - - writer.write(NL); - writer.write(CLS_JAVADOC); - writer.write(NL); - - writer.write("public class " + serClsName + " implements MessageSerializer<" + type.getSimpleName() + "> {" + NL); - } - - /** */ - private boolean marshallableMessage() { - return env.getTypeUtils().isAssignable(type.asType(), marshallableMsgType); - } - /** */ private boolean sameType(TypeMirror type, String typeStr) { return env.getTypeUtils().isSameType(type, type(typeStr)); @@ -1072,11 +837,6 @@ private boolean sameType(TypeMirror type, Class cls) { return env.getTypeUtils().isSameType(type, type(cls.getCanonicalName())); } - /** */ - private boolean assignableFrom(TypeMirror type, TypeMirror superType) { - return env.getTypeUtils().isAssignable(type, superType); - } - /** */ public static boolean enumType(ProcessingEnvironment env, TypeMirror type) { Element element = env.getTypeUtils().asElement(type); @@ -1084,62 +844,11 @@ public static boolean enumType(ProcessingEnvironment env, TypeMirror type) { return element != null && element.getKind() == ElementKind.ENUM; } - /** */ - private TypeMirror type(String clazz) { - Elements elementUtils = env.getElementUtils(); - - TypeElement typeElement = elementUtils.getTypeElement(clazz); - - return typeElement != null ? typeElement.asType() : null; - } - - /** */ - private TypeMirror erasedType(TypeMirror type) { - return env.getTypeUtils().erasure(type); - } - /** Converts string "BYTE" to string "Byte", with first capital latter. */ private String capitalizeOnlyFirst(String input) { return input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase(); } - /** @return {@code true} if trying to generate file with the same content. */ - public static boolean identicalFileIsAlreadyGenerated(ProcessingEnvironment env, String srcCode, String fqnClsName) { - try { - String fileName = fqnClsName.replace('.', '/') + ".java"; - FileObject prevFile = env.getFiler().getResource(StandardLocation.SOURCE_OUTPUT, "", fileName); - - String prevFileContent; - try (Reader r = prevFile.openReader(true)) { - prevFileContent = content(r); - } - - // We are ok, for some reason the same file is already generated (Intellij IDEA might do it). - if (prevFileContent.contentEquals(srcCode)) - return true; - } - catch (Exception ignoredAttemptToGetExistingFile) { - // We have some other problem, not an existing file. - } - - return false; - } - - /** */ - private static String content(Reader reader) throws IOException { - BufferedReader br = new BufferedReader(reader); - StringBuilder sb = new StringBuilder(); - String line; - - while ((line = br.readLine()) != null) - sb.append(line).append(NL); - - // Delete last line separator. - sb.deleteCharAt(sb.length() - 1); - - return sb.toString(); - } - /** Checks that the Compress annotation is used only for supported types: Map and Message. */ private void checkTypeForCompress(TypeMirror type) { if (type.getKind() == TypeKind.DECLARED) { @@ -1150,4 +859,5 @@ private void checkTypeForCompress(TypeMirror type) { throw new IllegalArgumentException("Compress annotation is used for an unsupported type: " + type); } + } diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/NioField.java b/modules/codegen/src/main/java/org/apache/ignite/internal/NioField.java new file mode 100644 index 0000000000000..610a551d19765 --- /dev/null +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/NioField.java @@ -0,0 +1,32 @@ +/* + * 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks a {@link Message}-typed {@link Order @Order} field whose {@code unmarshalNio} runs in the NIO thread + * rather than being deferred to the worker thread. + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.FIELD) +public @interface NioField { +} diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/idto/IDTOSerializerGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/internal/idto/IDTOSerializerGenerator.java index acbd9ecd35b60..26cd7ed2bd642 100644 --- a/modules/codegen/src/main/java/org/apache/ignite/internal/idto/IDTOSerializerGenerator.java +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/idto/IDTOSerializerGenerator.java @@ -61,10 +61,10 @@ import org.apache.ignite.lang.IgniteBiTuple; import org.jetbrains.annotations.NotNull; -import static org.apache.ignite.internal.MessageSerializerGenerator.NL; -import static org.apache.ignite.internal.MessageSerializerGenerator.TAB; +import static org.apache.ignite.internal.MessageGenerator.NL; +import static org.apache.ignite.internal.MessageGenerator.TAB; +import static org.apache.ignite.internal.MessageGenerator.identicalFileIsAlreadyGenerated; import static org.apache.ignite.internal.MessageSerializerGenerator.enumType; -import static org.apache.ignite.internal.MessageSerializerGenerator.identicalFileIsAlreadyGenerated; import static org.apache.ignite.internal.idto.IgniteDataTransferObjectProcessor.DTO_CLASS; /** diff --git a/modules/codegen/src/main/java/org/apache/ignite/internal/idto/IgniteDataTransferObjectProcessor.java b/modules/codegen/src/main/java/org/apache/ignite/internal/idto/IgniteDataTransferObjectProcessor.java index ae119f63c3ae3..6be4b9f7fd10a 100644 --- a/modules/codegen/src/main/java/org/apache/ignite/internal/idto/IgniteDataTransferObjectProcessor.java +++ b/modules/codegen/src/main/java/org/apache/ignite/internal/idto/IgniteDataTransferObjectProcessor.java @@ -42,9 +42,9 @@ import javax.tools.Diagnostic; import javax.tools.JavaFileObject; -import static org.apache.ignite.internal.MessageSerializerGenerator.NL; -import static org.apache.ignite.internal.MessageSerializerGenerator.TAB; -import static org.apache.ignite.internal.MessageSerializerGenerator.identicalFileIsAlreadyGenerated; +import static org.apache.ignite.internal.MessageGenerator.NL; +import static org.apache.ignite.internal.MessageGenerator.TAB; +import static org.apache.ignite.internal.MessageGenerator.identicalFileIsAlreadyGenerated; import static org.apache.ignite.internal.idto.IDTOSerializerGenerator.CLS_JAVADOC; import static org.apache.ignite.internal.idto.IDTOSerializerGenerator.DTO_SERDES_INTERFACE; import static org.apache.ignite.internal.idto.IDTOSerializerGenerator.simpleName; diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/CdcResendCommandTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/CdcResendCommandTest.java index e259864e68b50..4d6512d15f931 100644 --- a/modules/control-utility/src/test/java/org/apache/ignite/util/CdcResendCommandTest.java +++ b/modules/control-utility/src/test/java/org/apache/ignite/util/CdcResendCommandTest.java @@ -161,7 +161,7 @@ public void testResendConflictVersion() throws Exception { // Override data from clusterId=2. KeyCacheObject key = new KeyCacheObjectImpl(0, null, cachex.affinity().partition(0)); CacheObject val = new CacheObjectImpl(1, null); - val.prepareMarshal(cachex.context().cacheObjectContext()); + val.marshal(cachex.context().cacheObjectContext()); GridCacheVersion conflict = new GridCacheVersion(1, 0, 1, (byte)2); diff --git a/modules/core/pom.xml b/modules/core/pom.xml index aebc94795a5f5..1dfe5e39a8b45 100644 --- a/modules/core/pom.xml +++ b/modules/core/pom.xml @@ -231,6 +231,13 @@ test + + com.tngtech.archunit + archunit-junit4 + 1.4.1 + test + + com.google.testing.compile compile-testing 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 b1c36a9015827..13be8fa4dc102 100644 --- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java +++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java @@ -1967,6 +1967,10 @@ public final class IgniteSystemProperties extends IgniteCommonsSystemProperties @SystemProperty(value = "Packages list to expose in configuration view") public static final String IGNITE_CONFIGURATION_VIEW_PACKAGES = "IGNITE_CONFIGURATION_VIEW_PACKAGES"; + /** Enables the assertion that a message is finish-unmarshalled at most once. For tests; off in production. */ + @SystemProperty("Enables the message finish-unmarshal-once self-check (tests only)") + public static final String IGNITE_MESSAGE_UNMARSHAL_ONCE_CHECK = "IGNITE_MESSAGE_UNMARSHAL_ONCE_CHECK"; + /** * Enforces singleton. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java index 1af6f8945cff7..69f977c28a82c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java @@ -355,7 +355,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [5000 - 5500]: Utility messages. Most of them originally come from Discovery. msgIdx = 5000; withNoSchema(CompressedMessage.class); - withNoSchemaResolvedClassLoader(ErrorMessage.class); + withNoSchema(ErrorMessage.class); withNoSchema(InetSocketAddressMessage.class); withNoSchema(InetAddressMessage.class); withNoSchema(TcpDiscoveryNode.class); @@ -365,8 +365,8 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C withNoSchema(GridCacheVersion.class); withNoSchema(GridCacheVersionEx.class); withNoSchema(WALPointer.class); - withNoSchemaResolvedClassLoader(SerializableDataBagItemWrapper.class); - withSchemaResolvedClassLoader(GridTopicMessage.class); + withNoSchema(SerializableDataBagItemWrapper.class); + withSchema(GridTopicMessage.class); withNoSchema(GridIntList.class); // [5700 - 5900]: Discovery originated messages. @@ -655,7 +655,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C withNoSchema(MetadataRequestMessage.class); withNoSchema(MetadataResponseMessage.class); withNoSchema(MarshallerMappingItem.class); - withSchemaResolvedClassLoader(BinaryMetadataVersionInfo.class); + withSchema(BinaryMetadataVersionInfo.class); withNoSchema(CacheBinaryDataBagItem.class); withNoSchema(MappedName.class); withNoSchema(MarshallerDataBagItem.class); @@ -679,12 +679,12 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C withNoSchema(IgniteDiagnosticResponse.class); withNoSchema(WalStateAckMessage.class); withNoSchema(CacheConfigurationEnrichment.class); - withNoSchemaResolvedClassLoader(DynamicCacheChangeRequest.class); + withNoSchema(DynamicCacheChangeRequest.class); withNoSchema(PartitionHashRecord.class); withNoSchema(TransactionsHashRecord.class); withNoSchema(ClusterIdAndTag.class); withNoSchema(ClusterUpdateNotifierDataBagItem.class); - withNoSchemaResolvedClassLoader(PluginsDataBagItem.class); + withNoSchema(PluginsDataBagItem.class); withSchema(EventsDataBagItem.class); // [13400 - 13500]: Operation context messages. @@ -700,28 +700,18 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C assert msgIdx <= MAX_MESSAGE_ID; } - /** Registers message using {@link #dfltMarsh} and {@link #dftlClsLdr}. */ + /** Registers message using {@link #dfltMarsh}. */ private void withNoSchema(Class cls) { - register(cls, dfltMarsh, dftlClsLdr); + register(cls, dfltMarsh); } - /** Registers message using {@link #schemaAwareMarsh} and {@link #dftlClsLdr}. */ + /** Registers message using {@link #schemaAwareMarsh}. */ private void withSchema(Class cls) { - register(cls, schemaAwareMarsh, dftlClsLdr); - } - - /** Registers message using {@link #dfltMarsh} and {@link #resolvedClsLdr}. */ - private void withNoSchemaResolvedClassLoader(Class cls) { - register(cls, dfltMarsh, resolvedClsLdr); - } - - /** Registers message using {@link #schemaAwareMarsh} and {@link #resolvedClsLdr}. */ - private void withSchemaResolvedClassLoader(Class cls) { - register(cls, schemaAwareMarsh, resolvedClsLdr); + register(cls, schemaAwareMarsh); } /** Registers message using incrementing {@link #msgIdx} as the message id/type. */ - private void register(Class cls, Marshaller marsh, ClassLoader clsLrd) { - register(factory, cls, msgIdx++, marsh, clsLrd); + private void register(Class cls, Marshaller marsh) { + register(factory, cls, msgIdx++, marsh); } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java index 1ac2ce2bc9227..cad29b7b12909 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java @@ -563,7 +563,7 @@ void p2pUnmarshal(Marshaller marsh, @Nullable ClassLoader ldr) throws IgniteChec } /** {@inheritDoc} */ - @Override public void prepare(GridDeploymentInfo depInfo) { + @Override public void deploy(GridDeploymentInfo depInfo) { assert evt instanceof CacheEvent; this.depInfo = depInfo; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridJobExecuteRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/GridJobExecuteRequest.java index 37e23f5b8b9a0..376d05db9db07 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridJobExecuteRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridJobExecuteRequest.java @@ -451,7 +451,7 @@ public AffinityTopologyVersion topologyVersion() { /** * @param marsh Marshaller. */ - public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { + public void marshal(Marshaller marsh) throws IgniteCheckedException { jobBytes = U.marshal(marsh, job); topPredBytes = U.marshal(marsh, topPred); siblingsBytes = U.marshal(marsh, siblings); @@ -463,7 +463,7 @@ public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { * @param marsh Marshaller. * @param ldr Class loader. */ - public void finishUnmarshal(Marshaller marsh, ClassLoader ldr) throws IgniteCheckedException { + public void unmarshal(Marshaller marsh, ClassLoader ldr) throws IgniteCheckedException { assert top != null || topPredBytes != null; assert sesAttrsBytes != null || !sesFullSup; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridJobSiblingsResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/GridJobSiblingsResponse.java index 99f537e9ab325..d31c9fff4aeef 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridJobSiblingsResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridJobSiblingsResponse.java @@ -18,19 +18,18 @@ package org.apache.ignite.internal; import java.util.Collection; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.compute.ComputeJobSibling; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; /** * Job siblings response. */ -public class GridJobSiblingsResponse implements MarshallableMessage { +public class GridJobSiblingsResponse implements Message { /** */ - private @Nullable Collection siblings; + @Marshalled("siblingsBytes") + @Nullable Collection siblings; /** */ @Order(0) @@ -57,23 +56,6 @@ public GridJobSiblingsResponse(@Nullable Collection siblings) return siblings; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (siblings != null) - siblingsBytes = U.marshal(marsh, siblings); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - assert marsh != null; - - if (siblingsBytes != null) { - siblings = U.unmarshal(marsh, siblingsBytes, null); - - siblingsBytes = null; - } - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridJobSiblingsResponse.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridTopicMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/GridTopicMessage.java index 2f34b53f27360..35547f804aacd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridTopicMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridTopicMessage.java @@ -21,6 +21,7 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.jetbrains.annotations.Nullable; /** Message wrapper for grid topic. */ @@ -60,13 +61,13 @@ public static int ordinal(GridTopicMessage msg) { } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { if (ord < 0 && topic != null) topicBytes = U.marshal(marsh, topic); } /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (ord < 0 && topicBytes != null) { topic = U.unmarshal(marsh, topicBytes, clsLdr); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index 063774e7b13b5..60d7e5ff213c4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -222,6 +222,7 @@ import org.apache.ignite.thread.IgniteThread; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import static java.util.Collections.singleton; import static java.util.Optional.ofNullable; @@ -1319,7 +1320,8 @@ else if (e instanceof IgniteCheckedException) } /** */ - private void initMessageFactory() throws IgniteCheckedException { + @TestOnly + public void initMessageFactory() throws IgniteCheckedException { MessageFactoryProvider[] msgs = ctx.plugins().extensions(MessageFactoryProvider.class); List compMsgs = new ArrayList<>(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/TxEntriesInfo.java b/modules/core/src/main/java/org/apache/ignite/internal/TxEntriesInfo.java index a5a9fcc6bc2f7..c4d4ec69175d4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/TxEntriesInfo.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/TxEntriesInfo.java @@ -20,14 +20,14 @@ import java.util.Collection; import java.util.HashSet; import java.util.Objects; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheMapEntry; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.extensions.communication.CacheIdAware; -/** */ -public final class TxEntriesInfo extends IgniteDiagnosticRequest.DiagnosticBaseInfo { +/** Diagnostic request carrying cache keys pending transaction lock info for a specific cache. */ +public final class TxEntriesInfo extends IgniteDiagnosticRequest.DiagnosticBaseInfo implements CacheIdAware { /** */ @Order(0) int cacheId; @@ -52,7 +52,6 @@ public TxEntriesInfo() { this.keys = new HashSet<>(keys); } - /** {@inheritDoc} */ @Override public void appendInfo(StringBuilder sb, GridKernalContext ctx) { sb.append(U.nl()); @@ -65,16 +64,6 @@ public TxEntriesInfo() { return; } - try { - for (KeyCacheObject key : keys) - key.finishUnmarshal(cctx.cacheObjectContext(), null); - } - catch (IgniteCheckedException e) { - ctx.cluster().diagnosticLog().error("Failed to unmarshal key: " + e, e); - - sb.append("Failed to unmarshal key: ").append(e).append(U.nl()); - } - sb.append("Cache entries [cacheId=").append(cacheId) .append(", cacheName=").append(cctx.name()).append("]: "); @@ -111,4 +100,9 @@ public TxEntriesInfo() { @Override public int hashCode() { return Objects.hash(getClass(), cacheId); } + + /** {@inheritDoc} */ + @Override public int cacheId() { + return cacheId; + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java index 2192272747cd9..f5583b2244827 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java @@ -50,6 +50,7 @@ import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageMapType; import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.plugin.extensions.communication.MessageType; import org.apache.ignite.plugin.extensions.communication.MessageWriter; import org.jetbrains.annotations.Nullable; @@ -925,7 +926,7 @@ public void writeGridLongList(@Nullable GridLongList val) { public void writeMessage(Message msg, MessageWriter writer) { if (msg != null) { if (buf.hasRemaining()) - nestedWrite(writer, () -> msgFactory.serializer(msg.directType()).writeTo(msg, writer)); + nestedWrite(writer, () -> MessageSerializer.writeTo(msgFactory, msg, writer)); else lastFinished = false; } @@ -1571,7 +1572,7 @@ public T readMessage(MessageReader reader) { try { reader.beforeNestedRead(); - lastFinished = msgFactory.serializer(msg.directType()).readFrom(msg, reader); + lastFinished = MessageSerializer.readFrom(msgFactory, msg, reader); } finally { reader.afterNestedRead(lastFinished); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/CompressedMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/CompressedMessage.java index e3e46c43ff35c..bf4b57d901893 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/CompressedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/CompressedMessage.java @@ -27,14 +27,14 @@ import java.util.zip.InflaterInputStream; import org.apache.ignite.IgniteException; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.extensions.communication.NonMarshallableMessage; /** * Internal message used when transmitting fields annotated with @Compress over the network. *

* WARNING: CompressedMessage is not intended for explicit use in messages. */ -public class CompressedMessage implements Message { +public class CompressedMessage implements NonMarshallableMessage { /** Chunk size. */ static final int CHUNK_SIZE = 10 * 1024; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/ErrorMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/ErrorMessage.java index 02bb9ec0af99a..c74922f3d4a07 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/ErrorMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/ErrorMessage.java @@ -18,12 +18,12 @@ package org.apache.ignite.internal.managers.communication; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.jetbrains.annotations.Nullable; /** @@ -54,7 +54,7 @@ public ErrorMessage(@Nullable Throwable err) { } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { if (err == null) return; @@ -67,7 +67,7 @@ public ErrorMessage(@Nullable Throwable err) { } /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (errBytes == null) return; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java index a83e6ae8e7d41..5b6085686da72 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java @@ -91,6 +91,7 @@ import org.apache.ignite.internal.managers.discovery.CustomEventListener; import org.apache.ignite.internal.managers.eventstorage.GridEventStorageManager; import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.persistence.file.FileIO; import org.apache.ignite.internal.processors.cache.persistence.file.FileIOFactory; import org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIO; @@ -127,6 +128,7 @@ import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFormatter; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.plugin.extensions.communication.MessageReader; import org.apache.ignite.plugin.extensions.communication.MessageWriter; import org.apache.ignite.spi.IgniteSpiException; @@ -469,6 +471,9 @@ public void resetMetrics() { msg.getClass().getName() + ". Most likely GridCommunicationSpi is being used directly, " + "which is illegal - make sure to send messages only via GridProjection API."); } + catch (IgniteCheckedException e) { + throw new IgniteException(e); + } } @Override public void onDisconnected(UUID nodeId) { @@ -502,6 +507,8 @@ public void resetMetrics() { msg0.senderNodeId(nodeId); + msg0.onAfterRead(); + if (msg0.request()) { IgniteIoTestMessage res = new IgniteIoTestMessage(msg0.id(), false, null); @@ -511,6 +518,8 @@ public void resetMetrics() { res.copyDataFromRequest(msg0); try { + res.onBeforeWrite(); + sendToGridTopic(node, GridTopic.TOPIC_IO_TEST, res, GridIoPolicy.SYSTEM_POOL); } catch (IgniteCheckedException e) { @@ -555,6 +564,8 @@ public IgniteInternalFuture sendIoTest(List nodes, byte[] payload, ioTestMap().put(id, fut); + msg.onBeforeWrite(); + for (int i = 0; i < nodes.size(); i++) { ClusterNode node = nodes.get(i); @@ -592,6 +603,8 @@ public IgniteInternalFuture> sendIoTest( ioTestMap().put(id, fut); + msg.onBeforeWrite(); + try { sendToGridTopic(node, GridTopic.TOPIC_IO_TEST, msg, GridIoPolicy.SYSTEM_POOL); } @@ -1176,10 +1189,20 @@ private void onChannelOpened0(UUID rmtNodeId, GridIoMessage initMsg, Channel cha byte plc = initMsg.policy(); + MessageMarshaller.unmarshalNio(ctx.messageFactory(), initMsg, ctx); + pools.poolForPolicy(plc).execute(new Runnable() { @Override public void run() { - processOpenedChannel(initMsg.topic(), rmtNodeId, (SessionChannelMessage)initMsg.message(), - (SocketChannel)channel); + try { + MessageMarshaller.unmarshal(ctx.messageFactory(), initMsg, ctx); + + processOpenedChannel(initMsg.topic(), rmtNodeId, (SessionChannelMessage)initMsg.message(), + (SocketChannel)channel); + } + catch (IgniteCheckedException e) { + U.error(log, "Failed to process channel creation event due to exception " + + "[rmtNodeId=" + rmtNodeId + ", initMsg=" + initMsg + ']', e); + } } }); } @@ -1197,10 +1220,12 @@ private void onChannelOpened0(UUID rmtNodeId, GridIoMessage initMsg, Channel cha * @param msg Message bytes. * @param msgC Closure to call when message processing finished. */ - private void onMessage0(UUID nodeId, GridIoMessage msg, IgniteRunnable msgC) { + private void onMessage0(UUID nodeId, GridIoMessage msg, IgniteRunnable msgC) throws IgniteCheckedException { assert nodeId != null; assert msg != null; + MessageMarshaller.unmarshalNio(ctx.messageFactory(), msg, ctx); + Lock busyLock0 = busyLock.readLock(); busyLock0.lock(); @@ -1308,16 +1333,7 @@ private void processP2PMessage( try { threadProcessingMessage(true, msgC); - GridMessageListener lsnr = listenerGet0(msg.topic()); - - if (lsnr == null) - return; - - Object obj = msg.message(); - - assert obj != null; - - invokeListener(msg.policy(), lsnr, nodeId, obj, secSubjId(msg)); + processRegularMessage0(msg, nodeId); } finally { threadProcessingMessage(false, null); @@ -1451,11 +1467,23 @@ private void processRegularMessage0(GridIoMessage msg, UUID nodeId) { if (lsnr == null) return; - Object obj = msg.message(); + unmarshalPayload(msg); - assert obj != null; + invokeListener(msg.policy(), lsnr, nodeId, msg.message(), secSubjId(msg)); + } - invokeListener(msg.policy(), lsnr, nodeId, obj, secSubjId(msg)); + /** */ + private void unmarshalPayload(GridIoMessage msg) { + // Unmarshalled by GridCacheIoManager with the deployment loader; the loader here can't see its peer classes. + if (msg.message() instanceof GridCacheMessage) + return; + + try { + MessageMarshaller.unmarshal(ctx.messageFactory(), msg.message(), ctx); + } + catch (IgniteCheckedException e) { + throw new IgniteException("Failed to unmarshal message payload", e); + } } /** @@ -1933,6 +1961,8 @@ private IgniteInternalFuture openChannel( false ); + MessageMarshaller.marshal(ctx.messageFactory(), ioMsg, ctx, null); + try { return ((TcpCommunicationSpi)(CommunicationSpi)getSpi()).openChannel(node, ioMsg); } @@ -1983,7 +2013,6 @@ private void send( GridIoMessage ioMsg = createGridIoMessage(topic, msg, plc, ordered, timeout, skipOnTimeout); if (locNodeId.equals(node.id())) { - assert plc != P2P_POOL; CommunicationListener commLsnr = this.commLsnr; @@ -2002,25 +2031,74 @@ else if (async) ackC.apply(null); } else { + MessageMarshaller.marshal(ctx.messageFactory(), ioMsg, ctx, null); + + sendMarshalled(node, ioMsg, topic, msg, plc, ackC); + } + } + } + + /** + * Sends an already-marshalled message to a remote node. Marshalling is the caller's job, so one {@code ioMsg} can + * be prepared once and delivered to many nodes (see {@link #sendToMany}). + */ + private void sendMarshalled(ClusterNode node, GridIoMessage ioMsg, Object topic, Message msg, byte plc, + IgniteInClosure ackC) throws IgniteCheckedException { + try { + if ((CommunicationSpi)getSpi() instanceof TcpCommunicationSpi) + getTcpCommunicationSpi().sendMessage(node, ioMsg, ackC); + else + getSpi().sendMessage(node, ioMsg); + } + catch (IgniteSpiException e) { + if (e.getCause() instanceof ClusterTopologyCheckedException) + throw (ClusterTopologyCheckedException)e.getCause(); + + if (!ctx.discovery().alive(node)) + throw new ClusterTopologyCheckedException("Failed to send message, node left: " + node.id(), e); + + throw new IgniteCheckedException("Failed to send message (node may have left the grid or " + + "TCP connection cannot be established due to firewall issues) " + + "[node=" + node + ", topic=" + topic + + ", msg=" + msg + ", policy=" + plc + ']', e); + } + } + + /** + * Marshals {@code msg} once and delivers it to every node, instead of re-marshalling per destination. The local + * node, if present, goes through the regular per-node path, unmarshalled. + */ + private void sendToMany(Collection nodes, Object topic, Message msg, byte plc, + boolean ordered, long timeout, boolean skipOnTimeout) throws IgniteCheckedException { + try (TraceSurroundings ignored = support(null)) { + GridIoMessage ioMsg = null; + + IgniteCheckedException err = null; + + for (ClusterNode node : nodes) { try { - if ((CommunicationSpi)getSpi() instanceof TcpCommunicationSpi) - getTcpCommunicationSpi().sendMessage(node, ioMsg, ackC); - else - getSpi().sendMessage(node, ioMsg); - } - catch (IgniteSpiException e) { - if (e.getCause() instanceof ClusterTopologyCheckedException) - throw (ClusterTopologyCheckedException)e.getCause(); + if (locNodeId.equals(node.id())) + send(node, topic, msg, plc, ordered, timeout, skipOnTimeout, null, false); + else { + if (ioMsg == null) { + ioMsg = createGridIoMessage(topic, msg, plc, ordered, timeout, skipOnTimeout); - if (!ctx.discovery().alive(node)) - throw new ClusterTopologyCheckedException("Failed to send message, node left: " + node.id(), e); + MessageMarshaller.marshal(ctx.messageFactory(), ioMsg, ctx, null); + } - throw new IgniteCheckedException("Failed to send message (node may have left the grid or " + - "TCP connection cannot be established due to firewall issues) " + - "[node=" + node + ", topic=" + topic + - ", msg=" + msg + ", policy=" + plc + ']', e); + sendMarshalled(node, ioMsg, topic, msg, plc, null); + } + } + catch (IgniteCheckedException e) { + if (err == null) + err = e; + else + err.addSuppressed(e); } } + + if (err != null) + throw err; } } @@ -2188,22 +2266,7 @@ void sendOrderedMessageToGridTopic( throws IgniteCheckedException { assert timeout > 0 || skipOnTimeout; - IgniteCheckedException err = null; - - for (ClusterNode node : nodes) { - try { - send(node, topic, msg, plc, true, timeout, skipOnTimeout, null, false); - } - catch (IgniteCheckedException e) { - if (err == null) - err = e; - else - err.addSuppressed(e); - } - } - - if (err != null) - throw err; + sendToMany(nodes, topic, msg, plc, true, timeout, skipOnTimeout); } /** @@ -2219,22 +2282,7 @@ public void sendToGridTopic( Message msg, byte plc ) throws IgniteCheckedException { - IgniteCheckedException err = null; - - for (ClusterNode node : nodes) { - try { - send(node, topic, msg, plc, false, 0, false, null, false); - } - catch (IgniteCheckedException e) { - if (err == null) - err = e; - else - err.addSuppressed(e); - } - } - - if (err != null) - throw err; + sendToMany(nodes, topic, msg, plc, false, 0, false); } /** @@ -3812,7 +3860,9 @@ void unwind(GridMessageListener lsnr) { MTC.span().addTag(SpanTags.MESSAGE, () -> traceName(fmc.message)); - invokeListener(plc, lsnr, nodeId, mc.message.message(), secSubjId(mc.message)); + unmarshalPayload(mc.message); + + invokeListener(mc.message.policy(), lsnr, nodeId, mc.message.message(), secSubjId(mc.message)); } finally { if (mc.closure != null) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java index 1865868a71a53..e623ff5696524 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java @@ -19,6 +19,7 @@ import org.apache.ignite.internal.ExecutorAwareMessage; import org.apache.ignite.internal.GridTopicMessage; +import org.apache.ignite.internal.NioField; import org.apache.ignite.internal.OperationContextMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.GridCacheMessage; @@ -41,6 +42,7 @@ public class GridIoMessage implements Message, SpanTransport { byte plc; /** Topic message. */ + @NioField @Order(1) @GridToStringInclude GridTopicMessage topicMsg; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/IgniteIoTestMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/IgniteIoTestMessage.java index d95ead4f902de..afa447e0d5c3d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/IgniteIoTestMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/IgniteIoTestMessage.java @@ -18,16 +18,14 @@ package org.apache.ignite.internal.managers.communication; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; /** * */ -public class IgniteIoTestMessage implements MarshallableMessage { +public class IgniteIoTestMessage implements Message { /** */ private static final byte FLAG_PROC_FROM_NIO = 1; @@ -241,8 +239,8 @@ public long responseReceivedTsMillis() { } /** - * This method is called to initialize tracing variables. - * TODO: introduce direct message lifecycle API? + * Captures the receive timestamp. Invoked by {@code GridIoManager} right after the message is received, + * not during unmarshalling. */ public void onAfterRead() { if (req && reqRcvTs == 0) { @@ -259,8 +257,8 @@ public void onAfterRead() { } /** - * This method is called to initialize tracing variables. - * TODO: introduce direct message lifecycle API? + * Captures the send timestamp. Invoked by {@code GridIoManager} right before the message is sent, + * not during marshalling. */ public void onBeforeWrite() { if (req && reqSndTs == 0) { @@ -324,16 +322,6 @@ public void senderNodeId(UUID sndNodeId) { this.sndNodeId = sndNodeId; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - onBeforeWrite(); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - onAfterRead(); - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(IgniteIoTestMessage.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/IgniteMessageFactoryImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/IgniteMessageFactoryImpl.java index 6c1d45ef16438..6f52d1220fb38 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/IgniteMessageFactoryImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/IgniteMessageFactoryImpl.java @@ -20,9 +20,11 @@ import java.lang.reflect.Array; import java.util.function.Supplier; import org.apache.ignite.IgniteException; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.jetbrains.annotations.Nullable; @@ -42,6 +44,13 @@ public class IgniteMessageFactoryImpl implements MessageFactory { /** Message serializers. */ private final MessageSerializer[] msgSerializers = (MessageSerializer[])Array.newInstance(MessageSerializer.class, ARR_SIZE); + /** Message marshallers (null entry = no marshaller registered for that type). */ + private final MessageMarshaller[] msgMarshallers = (MessageMarshaller[])Array.newInstance(MessageMarshaller.class, ARR_SIZE); + + /** Message deployers (null entry = no deployer registered for that type). */ + private final GridCacheMessageDeployer[] msgDeployers = + (GridCacheMessageDeployer[])Array.newInstance(GridCacheMessageDeployer.class, ARR_SIZE); + /** Initialized flag. If {@code true} then new message type couldn't be registered. */ private boolean initialized; @@ -69,8 +78,17 @@ public IgniteMessageFactoryImpl(MessageFactoryProvider[] factories) { initialized = true; } - /** {@inheritDoc} */ - @Override public void register(short directType, Supplier supplier, MessageSerializer serializer) throws IgniteException { + /** + * Registers a message type with a serializer, an optional marshaller, and an optional deployer. + * + * @param directType Direct type. + * @param supplier Message factory. + * @param serializer Message serializer. + * @param marshaller Message marshaller, or {@code null} for NonMarshallableMessage types. + * @param deployer Message deployer, or {@code null} for messages without deployable fields. + */ + @Override public void register(short directType, Supplier supplier, MessageSerializer serializer, + @Nullable MessageMarshaller marshaller, @Nullable GridCacheMessageDeployer deployer) throws IgniteException { if (initialized) { throw new IllegalStateException("Message factory is already initialized. " + "Registration of new message types is forbidden."); @@ -91,6 +109,8 @@ public IgniteMessageFactoryImpl(MessageFactoryProvider[] factories) { if (curr == null) { msgSuppliers[idx] = supplier; msgSerializers[idx] = serializer; + msgMarshallers[idx] = marshaller; + msgDeployers[idx] = deployer; minIdx = Math.min(idx, minIdx); @@ -118,11 +138,7 @@ public IgniteMessageFactoryImpl(MessageFactoryProvider[] factories) { return supplier.get(); } - /** - * @param directType Message direct type. - * @return Message instance. - * @throws IgniteException If there are no any message factory for given {@code directType}. - */ + /** {@inheritDoc} */ @Override public MessageSerializer serializer(short directType) { MessageSerializer serializer = msgSerializers[directTypeToIndex(directType)]; @@ -132,6 +148,16 @@ public IgniteMessageFactoryImpl(MessageFactoryProvider[] factories) { return serializer; } + /** {@inheritDoc} */ + @Override public @Nullable MessageMarshaller marshaller(short directType) { + return msgMarshallers[directTypeToIndex(directType)]; + } + + /** {@inheritDoc} */ + @Override public @Nullable GridCacheMessageDeployer deployer(short directType) { + return msgDeployers[directTypeToIndex(directType)]; + } + /** * Returns direct types of all registered messages. * diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/GridEventStorageMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/GridEventStorageMessage.java index 688145e87b971..022b929519e06 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/GridEventStorageMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/GridEventStorageMessage.java @@ -25,7 +25,7 @@ import org.apache.ignite.configuration.DeploymentMode; import org.apache.ignite.events.Event; import org.apache.ignite.internal.GridTopicMessage; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.communication.ErrorMessage; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -34,6 +34,7 @@ import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.jetbrains.annotations.Nullable; /** @@ -52,7 +53,8 @@ public class GridEventStorageMessage implements MarshallableMessage { byte[] filterBytes; /** */ - private Collection evts; + @Marshalled("evtsBytes") + Collection evts; /** */ @Order(2) @@ -197,21 +199,14 @@ String userVersion() { } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { if (filter != null) filterBytes = U.marshal(marsh, filter); - - if (evts != null) - evtsBytes = U.marshal(marsh, evts); } /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader ldr) throws IgniteCheckedException { - if (evtsBytes != null) { - evts = U.unmarshal(marsh, evtsBytes, ldr); - - evtsBytes = null; - } + @Override public void unmarshal(Marshaller marsh, ClassLoader ldr) throws IgniteCheckedException { + // No-op. } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/plugin/AbstractMarshallableMessageFactoryProvider.java b/modules/core/src/main/java/org/apache/ignite/internal/plugin/AbstractMarshallableMessageFactoryProvider.java index 5ac1f2472997f..d998eeceebd13 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/plugin/AbstractMarshallableMessageFactoryProvider.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/plugin/AbstractMarshallableMessageFactoryProvider.java @@ -18,17 +18,21 @@ package org.apache.ignite.internal.plugin; import java.lang.reflect.Constructor; +import java.util.function.Supplier; import org.apache.ignite.IgniteException; import org.apache.ignite.configuration.IgniteConfiguration; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.binary.BinaryMarshaller; -import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.marshaller.jdk.JdkMarshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.apache.ignite.plugin.extensions.communication.NonMarshallableMessage; +import org.jetbrains.annotations.Nullable; /** * An extension of {@link MessageFactoryProvider} allowing to use provided schema-aware marshaller @@ -38,15 +42,9 @@ public abstract class AbstractMarshallableMessageFactoryProvider implements Mess /** Default schema-less marshaller. */ protected Marshaller dfltMarsh; - /** Default class loader. */ - protected final ClassLoader dftlClsLdr = U.gridClassLoader(); - /** Schema-aware marshaller like {@link BinaryMarshaller}. */ protected Marshaller schemaAwareMarsh; - /** Resolved (configured) class loader like {@link IgniteConfiguration#setClassLoader(ClassLoader)}. */ - protected ClassLoader resolvedClsLdr; - /** * @param dfltMarsh Default schema-less marshaller like {@link JdkMarshaller}. * @param schemaAwareMarsh Schema-aware marshaller like {@link BinaryMarshaller}. @@ -55,41 +53,69 @@ public abstract class AbstractMarshallableMessageFactoryProvider implements Mess public void init(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, ClassLoader resolvedClsLdr) { this.dfltMarsh = dfltMarsh; this.schemaAwareMarsh = schemaAwareMarsh; - this.resolvedClsLdr = resolvedClsLdr; } - /** Registers message automatically generating message supplier and serializer. */ - protected static void register(MessageFactory factory, Class cls, short id, Marshaller marsh, - ClassLoader clsLrd) { + /** Registers a message with its generated serializer, marshaller (if marshallable), and deployer (if any). */ + protected static void register(MessageFactory factory, Class cls, short id, Marshaller marsh) { Constructor ctor; - MessageSerializer serializer; try { ctor = cls.getConstructor(); + } + catch (NoSuchMethodException e) { + throw new IgniteException("Failed to register message of type " + cls.getSimpleName(), e); + } + + register(factory, cls, id, () -> { + try { + return ctor.newInstance(); + } + catch (Exception e) { + throw new IgniteException("Failed to create message of type " + cls.getSimpleName(), e); + } + }, marsh); + } + + /** + * Registers a message with a caller-provided {@code supplier} and its generated serializer, marshaller (if + * marshallable), and deployer (if any). Use this overload when {@code cls} is package-private and so cannot be + * instantiated by reflection from this package — pass an in-package {@code ::new} reference as {@code supplier}. + */ + protected static void register(MessageFactory factory, Class cls, short id, + Supplier supplier, Marshaller marsh) { + MessageSerializer serializer = loadGenerated(cls, "Serializer", marsh); + + MessageMarshaller marshaller = NonMarshallableMessage.class.isAssignableFrom(cls) + ? null + : loadGenerated(cls, "Marshaller", marsh); - boolean marshallable = MarshallableMessage.class.isAssignableFrom(cls); + GridCacheMessageDeployer deployer = loadGenerated(cls, "Deployer", marsh); - Class serCls = Class.forName(cls.getName() + (marshallable ? "MarshallableSerializer" : "Serializer")); + factory.register(id, supplier, serializer, marshaller, deployer); + } - serializer = marshallable - ? (MessageSerializer)serCls.getConstructor(Marshaller.class, ClassLoader.class).newInstance(marsh, clsLrd) - : (MessageSerializer)serCls.getConstructor().newInstance(); + /** + * Loads and instantiates the generated companion class {@code Serializer/Marshaller/Deployer}, or returns + * {@code null} when it does not exist. The sole declared constructor is used, passing {@code marsh} when it takes one. + */ + @SuppressWarnings("unchecked") + private static @Nullable T loadGenerated(Class cls, String suffix, Marshaller marsh) { + Class generated; + + try { + generated = Class.forName(cls.getName() + suffix); } - catch (Exception e) { - throw new IgniteException("Failed to register message of type " + cls.getSimpleName(), e); + catch (ClassNotFoundException ignored) { + return null; } - factory.register( - id, - () -> { - try { - return ctor.newInstance(); - } - catch (Exception e) { - throw new IgniteException("Failed to create message of type " + cls.getSimpleName(), e); - } - }, - serializer - ); + try { + Constructor ctor = generated.getConstructors()[0]; + + return (T)(ctor.getParameterCount() == 0 ? ctor.newInstance() : ctor.newInstance(marsh)); + } + catch (Exception e) { + throw new IgniteException("Failed to instantiate " + cls.getSimpleName() + suffix, e); + } } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryPredicate.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryPredicate.java index 36312a1591135..d8c8e7083ee62 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryPredicate.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryPredicate.java @@ -17,7 +17,6 @@ package org.apache.ignite.internal.processors.cache; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.plugin.extensions.communication.Message; @@ -25,19 +24,6 @@ * */ public interface CacheEntryPredicate extends IgnitePredicate, Message { - /** - * @param ctx Context. - * @throws IgniteCheckedException If failed. - */ - public void prepareMarshal(GridCacheContext ctx) throws IgniteCheckedException; - - /** - * @param ctx Context. - * @param ldr Class loader. - * @throws IgniteCheckedException If failed. - */ - public void finishUnmarshal(GridCacheContext ctx, ClassLoader ldr) throws IgniteCheckedException; - /** * @param locked Entry locked */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryPredicateAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryPredicateAdapter.java index 0c30dc615aa66..d41a3da341e63 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryPredicateAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryPredicateAdapter.java @@ -18,7 +18,6 @@ package org.apache.ignite.internal.processors.cache; import java.util.Objects; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -118,17 +117,4 @@ public CacheEntryPredicateType type() { throw new IllegalStateException("Unknown cache entry predicate type: " + type); } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheContext ctx, ClassLoader ldr) throws IgniteCheckedException { - if (type == CacheEntryPredicateType.VALUE) - val.finishUnmarshal(ctx.cacheObjectContext(), ldr); - } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheContext ctx) throws IgniteCheckedException { - if (type == CacheEntryPredicateType.VALUE) - val.prepareMarshal(ctx.cacheObjectContext()); - } - } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheInvokeDirectResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheInvokeDirectResult.java index 1276c6b63c82c..4490be4c1dfc9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheInvokeDirectResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheInvokeDirectResult.java @@ -19,7 +19,6 @@ import javax.cache.processor.EntryProcessor; import javax.cache.processor.MutableEntry; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.communication.ErrorMessage; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -111,19 +110,6 @@ public CacheObject result() { return ErrorMessage.error(errMsg); } - /** - * @param ctx Cache context. - * @throws IgniteCheckedException If failed. - */ - public void prepareMarshal(GridCacheContext ctx) throws IgniteCheckedException { - key.prepareMarshal(ctx.cacheObjectContext()); - - assert unprepareRes == null : "marshalResult() was not called for the result: " + this; - - if (res != null) - res.prepareMarshal(ctx.cacheObjectContext()); - } - /** * Converts the entry processor unprepared result to a cache object instance. * @@ -139,19 +125,6 @@ public void marshalResult(GridCacheContext ctx) { } } - /** - * @param ctx Cache context. - * @param ldr Class loader. - * @throws IgniteCheckedException If failed. - */ - public void finishUnmarshal(GridCacheContext ctx, ClassLoader ldr) throws IgniteCheckedException { - key.finishUnmarshal(ctx.cacheObjectContext(), ldr); - - if (res != null) - res.finishUnmarshal(ctx.cacheObjectContext(), ldr); - } - - /** {@inheritDoc} */ @Override public String toString() { return S.toString(CacheInvokeDirectResult.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectByteArrayImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectByteArrayImpl.java index 2119c99b9c1bb..608d6fdc8868b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectByteArrayImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectByteArrayImpl.java @@ -56,7 +56,7 @@ public CacheObjectByteArrayImpl(byte[] val) { } /** {@inheritDoc} */ - @Override public void finishUnmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { + @Override public void unmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { // No-op. } @@ -118,7 +118,7 @@ public CacheObjectByteArrayImpl(byte[] val) { } /** {@inheritDoc} */ - @Override public void prepareMarshal(CacheObjectValueContext ctx) throws IgniteCheckedException { + @Override public void marshal(CacheObjectValueContext ctx) throws IgniteCheckedException { // No-op. } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectImpl.java index fabf36ac20a08..cc4be8e76e5cf 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectImpl.java @@ -105,7 +105,7 @@ else if (ctx.isPeerClassLoadingEnabled()) } /** {@inheritDoc} */ - @Override public void prepareMarshal(CacheObjectValueContext ctx) throws IgniteCheckedException { + @Override public void marshal(CacheObjectValueContext ctx) throws IgniteCheckedException { assert val != null || valBytes != null; if (valBytes == null) @@ -113,7 +113,7 @@ else if (ctx.isPeerClassLoadingEnabled()) } /** {@inheritDoc} */ - @Override public void finishUnmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { + @Override public void unmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { assert val != null || valBytes != null; if (val == null && ctx.storeValue()) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectNotResolvedException.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectNotResolvedException.java new file mode 100644 index 0000000000000..09440bf117603 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectNotResolvedException.java @@ -0,0 +1,32 @@ +/* + * 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.cache; + +/** + * Thrown by {@link KeyCacheObjectImpl#hashCode()} when the object has not been deserialized yet, + * which happens when the owning cache has been removed before {@code unmarshal} could complete. + */ +public class CacheObjectNotResolvedException extends RuntimeException { + /** */ + private static final long serialVersionUID = 0L; + + /** */ + public CacheObjectNotResolvedException() { + super(null, null, true, false); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DeployableMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DeployableMessage.java new file mode 100644 index 0000000000000..a9848ab3e104e --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DeployableMessage.java @@ -0,0 +1,35 @@ +/* + * 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.cache; + +import org.apache.ignite.IgniteCheckedException; + +/** + * A {@link GridCacheMessage} with custom deployment logic that cannot be inferred from field types (conditional + * deployment, non-standard accessors, etc.). The generated {@code *Deployer} calls {@link #deploy} after + * its inferred field deployment, mirroring how a generated marshaller calls {@code MarshallableMessage#marshal}. + */ +public interface DeployableMessage { + /** + * Prepares deployment info for fields whose handling cannot be inferred from their type. + * + * @param ctx Cache shared context. + * @throws IgniteCheckedException If failed. + */ + void deploy(GridCacheSharedContext ctx) throws IgniteCheckedException; +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java index 79c2f7d90bf42..43e375c45d7d0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java @@ -19,25 +19,23 @@ import java.io.Serializable; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.NearCacheConfiguration; import org.apache.ignite.internal.CoreMessagesProvider; import org.apache.ignite.internal.GridKernalContext; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.query.QuerySchema; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.T2; -import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; /** * Cache start/stop request. */ -public class DynamicCacheChangeRequest implements MarshallableMessage, Serializable { +public class DynamicCacheChangeRequest implements Message, Serializable { /** */ private static final long serialVersionUID = 0L; @@ -56,7 +54,8 @@ public class DynamicCacheChangeRequest implements MarshallableMessage, Serializa /** Cache start configuration. */ @GridToStringExclude - private CacheConfiguration startCfg; + @Marshalled("cfgBytes") + CacheConfiguration startCfg; /** Bytes of {@link #startCfg}. */ @Order(3) @@ -72,7 +71,8 @@ public class DynamicCacheChangeRequest implements MarshallableMessage, Serializa /** Near cache configuration. */ @GridToStringExclude - private NearCacheConfiguration nearCacheCfg; + @Marshalled("nearCfgBytes") + NearCacheConfiguration nearCacheCfg; /** Bytes of {@link #nearCacheCfg}. */ @Order(6) @@ -123,6 +123,7 @@ public class DynamicCacheChangeRequest implements MarshallableMessage, Serializa boolean resetLostPartitions; /** Dynamic schema. */ + @Marshalled("schemaBytes") QuerySchema schema; /** Bytes of {@link #schema}. */ @@ -166,32 +167,6 @@ public DynamicCacheChangeRequest(UUID reqId, String cacheName, UUID initiatingNo this.initiatingNodeId = initiatingNodeId; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - cfgBytes = U.marshal(marsh, startCfg); - - if (nearCacheCfg != null) - nearCfgBytes = U.marshal(marsh, nearCacheCfg); - - if (schema != null) - schemaBytes = U.marshal(marsh, schema); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - startCfg = U.unmarshal(marsh, cfgBytes, clsLdr); - - if (nearCfgBytes != null) - nearCacheCfg = U.unmarshal(marsh, nearCfgBytes, clsLdr); - - if (schemaBytes != null) - schema = U.unmarshal(marsh, schemaBytes, clsLdr); - - cfgBytes = null; - nearCfgBytes = null; - schemaBytes = null; - } - /** * @param ctx Context. * @param cacheName Cache name. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java index 2fe29746e7a7e..f6d51ada3ff7e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java @@ -212,19 +212,6 @@ public abstract class GridCacheAdapter implements IgniteInternalCache, Object>() { - @Nullable @Override public Object applyx(IgniteInternalFuture fut) - throws IgniteCheckedException { - return fut.get().value(); - } - - @Override public String toString() { - return "Cache return value to value converter."; - } - }; - /** {@link GridCacheReturn}-to-null conversion. */ protected static final IgniteClosure RET2NULL = new CX1, Object>() { @@ -252,6 +239,19 @@ public abstract class GridCacheAdapter implements IgniteInternalCache, Object>() { + @Nullable @Override public Object applyx(IgniteInternalFuture fut) + throws IgniteCheckedException { + return fut.get().value(ctx); + } + + @Override public String toString() { + return "Cache return value to value converter."; + } + }; + /** Last asynchronous future. */ protected ThreadLocal lastFut = new ThreadLocal() { @Override protected FutureHolder initialValue() { @@ -1827,7 +1827,7 @@ protected V getAndPut0(final K key, final V val, @Nullable final CacheEntryPredi throws IgniteCheckedException { return syncOp(new SyncOp(true) { @Override public V op(GridNearTxLocal tx) throws IgniteCheckedException { - return (V)tx.putAsync(ctx, null, key, val, true, filter).get().value(); + return (V)tx.putAsync(ctx, null, key, val, true, filter).get().value(ctx); } @Override public String toString() { @@ -1880,7 +1880,7 @@ public IgniteInternalFuture getAndPutAsync0(final K key, @Nullable final CacheEntryPredicate filter) { return asyncOp(new AsyncOp() { @Override public IgniteInternalFuture op(GridNearTxLocal tx, AffinityTopologyVersion readyTopVer) { - return tx.putAsync(ctx, readyTopVer, key, val, true, filter).chain(RET2VAL); + return tx.putAsync(ctx, readyTopVer, key, val, true, filter).chain(ret2val); } @Override public String toString() { @@ -2067,7 +2067,7 @@ private EntryProcessorResult invoke0( (EntryProcessor)entryProcessor, args); - Map> resMap = fut.get().value(); + Map> resMap = fut.get().value(ctx); if (statsEnabled) metrics0().addInvokeTimeNanos(System.nanoTime() - start); @@ -2110,7 +2110,7 @@ private EntryProcessorResult invoke0( IgniteInternalFuture fut = tx.invokeAsync(ctx, null, keys, invokeVals, args); - Map> res = fut.get().value(); + Map> res = fut.get().value(ctx); if (statsEnabled) metrics0().addInvokeTimeNanos(System.nanoTime() - start); @@ -2161,7 +2161,7 @@ private EntryProcessorResult invoke0( if (performanceStatsEnabled) writeStatistics(OperationType.CACHE_INVOKE, start); - Map> resMap = ret.value(); + Map> resMap = ret.value(ctx); if (resMap != null) { assert resMap.isEmpty() || resMap.size() == 1 : resMap.size(); @@ -2220,7 +2220,7 @@ private EntryProcessorResult invoke0( assert ret != null; - return ret.value() != null ? ret.value() : Collections.emptyMap(); + return ret.value(ctx) != null ? ret.value(ctx) : Collections.emptyMap(); } }); } @@ -2271,8 +2271,8 @@ private EntryProcessorResult invoke0( assert ret != null; - return ret.value() != null - ? ret.>>value() + return ret.value(ctx) != null + ? ret.>>value(ctx) : Collections.>emptyMap(); } }); @@ -2303,7 +2303,7 @@ private EntryProcessorResult invoke0( args ); - Map> val = fut.get().value(); + Map> val = fut.get().value(ctx); if (statsEnabled) metrics0().addInvokeTimeNanos(System.nanoTime() - start); @@ -2549,7 +2549,7 @@ protected V getAndRemove0(final K key) throws IgniteCheckedException { null, /*singleRmv*/false); - V ret = fut.get().value(); + V ret = fut.get().value(ctx); if (ctx.config().getInterceptor() != null) { K key = keepBinary ? (K)ctx.unwrapBinaryIfNeeded(key0, true, false, null) : key0; @@ -2600,7 +2600,7 @@ protected IgniteInternalFuture getAndRemoveAsync0(final K key) { Collections.singletonList(key), /*retval*/true, null, - /*singleRmv*/false).chain(RET2VAL); + /*singleRmv*/false).chain(ret2val); } @Override public String toString() { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeployable.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeployable.java index 057ce897bac52..ffd5953a2f7e1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeployable.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeployable.java @@ -24,11 +24,11 @@ */ public interface GridCacheDeployable { /** - * Prepare deployment information. + * Applies the given deployment information. * * @param depInfo Deployment information. */ - public void prepare(GridDeploymentInfo depInfo); + public void deploy(GridDeploymentInfo depInfo); /** * @return Deployment bean. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentManager.java index ce2ceaa577771..125fe4ce94743 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentManager.java @@ -411,7 +411,7 @@ public void prepare(GridCacheDeployable deployable) throws IgnitePeerToPeerClass checkDeploymentIsCorrect(dep, deployable, true); if (dep != null) - deployable.prepare(dep); + deployable.deploy(dep); if (log.isDebugEnabled()) log.debug("Prepared grid cache deployable [dep=" + dep + ", deployable=" + deployable + ']'); @@ -449,7 +449,7 @@ private void checkDeploymentIsCorrect(GridDeploymentInfoBean deployment, GridCac assert depEnabled; // Do not return info if mode is CONTINUOUS. - // In this case deployment info will be set by GridCacheMessage.prepareObject(). + // In this case deployment info will be set by GridCacheMessage.deployObject(). if (cctx.gridConfig().getDeploymentMode() == CONTINUOUS) return null; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryInfo.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryInfo.java index d8d710f62368f..9896ce1bd989a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryInfo.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryInfo.java @@ -23,12 +23,14 @@ import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.CacheIdAware; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; /** * Entry information that gets passed over wire. */ -public class GridCacheEntryInfo implements Message { +public class GridCacheEntryInfo implements MarshallableMessage, CacheIdAware { /** */ private static final int SIZE_OVERHEAD = 3 * 8 /* reference */ + 4 /* int */ + 2 * 8 /* long */ + 32 /* version */; @@ -63,10 +65,8 @@ public class GridCacheEntryInfo implements Message { /** Deleted flag. */ private boolean deleted; - /** - * @return Cache ID. - */ - public int cacheId() { + /** {@inheritDoc} */ + @Override public int cacheId() { return cacheId; } @@ -175,16 +175,6 @@ public void setDeleted(boolean deleted) { this.deleted = deleted; } - /** - * @param ctx Context. - * @param ldr Loader. - * @throws IgniteCheckedException If failed. - */ - public void unmarshalValue(GridCacheContext ctx, ClassLoader ldr) throws IgniteCheckedException { - if (val != null) - val.finishUnmarshal(ctx.cacheObjectContext(), ldr); - } - /** * @param ctx Cache object context. * @return Marshalled size. @@ -201,26 +191,8 @@ public int marshalledSize(CacheObjectContext ctx) throws IgniteCheckedException return SIZE_OVERHEAD + size; } - /** - * @param ctx Cache context. - * @throws IgniteCheckedException In case of error. - */ - public void marshal(GridCacheContext ctx) throws IgniteCheckedException { - marshal(ctx.cacheObjectContext()); - } - - /** - * @param ctx Cache context. - * @throws IgniteCheckedException In case of error. - */ - public void marshal(CacheObjectContext ctx) throws IgniteCheckedException { - assert key != null; - - key.prepareMarshal(ctx); - - if (val != null) - val.prepareMarshal(ctx); - + /** {@inheritDoc} */ + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { if (expireTime == 0) expireTime = -1; else { @@ -231,30 +203,8 @@ public void marshal(CacheObjectContext ctx) throws IgniteCheckedException { } } - /** - * Unmarshalls entry. - * - * @param ctx Cache context. - * @param clsLdr Class loader. - * @throws IgniteCheckedException If unmarshalling failed. - */ - public void unmarshal(GridCacheContext ctx, ClassLoader clsLdr) throws IgniteCheckedException { - unmarshal(ctx.cacheObjectContext(), clsLdr); - } - - /** - * Unmarshalls entry. - * - * @param ctx Cache context. - * @param clsLdr Class loader. - * @throws IgniteCheckedException If unmarshalling failed. - */ - public void unmarshal(CacheObjectContext ctx, ClassLoader clsLdr) throws IgniteCheckedException { - key.finishUnmarshal(ctx, clsLdr); - - if (val != null) - val.finishUnmarshal(ctx, clsLdr); - + /** {@inheritDoc} */ + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { long remaining = expireTime; expireTime = remaining < 0 ? 0 : U.currentTimeMillis() + remaining; @@ -263,7 +213,7 @@ public void unmarshal(CacheObjectContext ctx, ClassLoader clsLdr) throws IgniteC if (expireTime < 0) expireTime = 0; } - + /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridCacheEntryInfo.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIdMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIdMessage.java index f0ebb72b7b5b1..1236d67451ac1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIdMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIdMessage.java @@ -20,20 +20,19 @@ import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.plugin.extensions.communication.CacheIdAware; /** * Message related to particular cache. */ -public abstract class GridCacheIdMessage extends GridCacheMessage { +public abstract class GridCacheIdMessage extends GridCacheMessage implements CacheIdAware { /** Cache ID. */ @GridToStringInclude @Order(0) public int cacheId; - /** - * @return Cache ID. - */ - public int cacheId() { + /** {@inheritDoc} */ + @Override public int cacheId() { return cacheId; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java index 4dfdb6b35997d..d47de55d1462b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java @@ -92,6 +92,7 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiInClosure; import org.apache.ignite.lang.IgniteUuid; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.thread.IgniteThread; import org.jetbrains.annotations.Nullable; @@ -741,7 +742,7 @@ else if (cacheMsg instanceof GridNearAtomicCheckUpdateRequest) * @param plc Message policy. * @throws IgniteCheckedException If failed. */ - private void processFailedMessage(UUID nodeId, + public void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInClosure c, byte plc) @@ -1095,7 +1096,7 @@ private boolean onSend(GridCacheMessage msg, @Nullable UUID destNodeId) throws I msg.messageId(idGen.incrementAndGet()); if (destNodeId == null || !cctx.localNodeId().equals(destNodeId)) { - msg.prepareMarshal(cctx); + GridCacheMessageDeployer.deploy(cctx.kernalContext().messageFactory(), msg, cctx); if (msg instanceof GridCacheDeployable && msg.addDeploymentInfo()) cctx.deploy().prepare((GridCacheDeployable)msg); @@ -1551,7 +1552,8 @@ private void unmarshall(UUID nodeId, GridCacheMessage cacheMsg) { log.debug("Set P2P context [senderId=" + nodeId + ", msg=" + cacheMsg + ']'); } - cacheMsg.finishUnmarshal(cctx, cctx.deploy().globalLoader()); + MessageMarshaller.unmarshal(cctx.kernalContext().messageFactory(), + cacheMsg, cctx.kernalContext(), null, cctx.deploy().globalLoader()); } catch (IgniteCheckedException e) { cacheMsg.onClassError(e); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java index d2ead2bb39d93..e50b225d1ef93 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java @@ -282,12 +282,12 @@ protected void value(@Nullable CacheObject val) { lockEntry(); try { - key.prepareMarshal(cctx.cacheObjectContext()); + key.marshal(cctx.cacheObjectContext()); kb = key.valueBytes(cctx.cacheObjectContext()); if (val != null) { - val.prepareMarshal(cctx.cacheObjectContext()); + val.marshal(cctx.cacheObjectContext()); vb = val.valueBytes(cctx.cacheObjectContext()); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java index ec670da2d1cbf..bff5af40d9174 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java @@ -32,7 +32,6 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.T2; -import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; @@ -200,27 +199,28 @@ public void lastAffinityChangedTopologyVersion(AffinityTopologyVersion topVer) { public abstract boolean addDeploymentInfo(); /** - * @param o Object to prepare for marshalling. + * @param o Object to deploy. * @param ctx Context. * @throws IgniteCheckedException If failed. */ - protected final void prepareObject(@Nullable Object o, GridCacheContext ctx) throws IgniteCheckedException { - prepareObject(o, ctx.shared()); + public final void deployObject(@Nullable Object o, @Nullable GridCacheContext ctx) throws IgniteCheckedException { + if (ctx != null) + deployObject(o, ctx.shared()); } /** - * @param o Object to prepare for marshalling. + * @param o Object to deploy. * @param ctx Context. * @throws IgniteCheckedException If failed. */ - protected final void prepareObject(@Nullable Object o, GridCacheSharedContext ctx) throws IgniteCheckedException { + final void deployObject(@Nullable Object o, GridCacheSharedContext ctx) throws IgniteCheckedException { assert addDepInfo || forceAddDepInfo; if (!skipPrepare && o != null) { GridDeploymentInfo d = ctx.deploy().globalDeploymentInfo(); if (d != null) { - prepare(d); + deploy(d); // Global deployment has been injected. skipPrepare = true; @@ -233,16 +233,22 @@ protected final void prepareObject(@Nullable Object o, GridCacheSharedContext ct ClassLoader ldr = U.detectClassLoader(cls); if (ldr instanceof GridDeploymentInfo) - prepare((GridDeploymentInfo)ldr); + deploy((GridDeploymentInfo)ldr); } } } + /** Forces deployment info to be added when peer-class-loading is enabled. */ + public final void forceDeploymentInfo(GridCacheSharedContext ctx) { + if (!addDepInfo && ctx.deploymentEnabled()) + addDepInfo = true; + } + /** * @param depInfo Deployment to set. - * @see GridCacheDeployable#prepare(GridDeploymentInfo) + * @see GridCacheDeployable#deploy(GridDeploymentInfo) */ - public final void prepare(GridDeploymentInfo depInfo) { + public final void deploy(GridDeploymentInfo depInfo) { if (depInfo != this.depInfo) { if (this.depInfo != null && depInfo instanceof GridDeployment) // Make sure not to replace remote deployment with local. @@ -262,72 +268,39 @@ public GridDeploymentInfoBean deployInfo() { return depInfo; } - /** - * This method is called before the whole message is serialized - * and is responsible for pre-marshalling state. - * - * @param ctx Cache context. - * @throws IgniteCheckedException If failed. - */ - public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - // No-op. - } - - /** - * This method is called after the message is deserialized and is responsible for - * unmarshalling state marshalled in {@link #prepareMarshal(GridCacheSharedContext)} method. - * - * @param ctx Context. - * @param ldr Class loader. - * @throws IgniteCheckedException If failed. - */ - public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - // No-op. - } - /** * @param info Entry to marshal. * @param ctx Context. * @param cacheObjCtx Cache object context. * @throws IgniteCheckedException If failed. */ - protected final void marshalInfo(GridCacheEntryInfo info, + public final void deployInfo(GridCacheEntryInfo info, GridCacheSharedContext ctx, CacheObjectContext cacheObjCtx ) throws IgniteCheckedException { assert ctx != null; if (info != null) { - info.marshal(cacheObjCtx); - if (addDepInfo) { if (info.key() != null) - prepareObject(info.key().value(cacheObjCtx, false), ctx); + deployObject(info.key().value(cacheObjCtx, false), ctx); CacheObject val = info.value(); if (val != null) { - val.finishUnmarshal(cacheObjCtx, ctx.deploy().globalLoader()); + val.unmarshal(cacheObjCtx, ctx.deploy().globalLoader()); - prepareObject(val.value(cacheObjCtx, false), ctx); + deployObject(val.value(cacheObjCtx, false), ctx); } } } } - /** - * @param info Entry to unmarshal. - * @param ctx Context. - * @param ldr Loader. - * @throws IgniteCheckedException If failed. - */ - protected final void unmarshalInfo(GridCacheEntryInfo info, GridCacheContext ctx, - ClassLoader ldr) throws IgniteCheckedException { - assert ldr != null; - assert ctx != null; - - if (info != null) - info.unmarshal(ctx.cacheObjectContext(), ldr); + /** Deploys all {@code infos}, resolving shared and cache-object contexts from {@code cctx}; no-op when {@code cctx} is absent. */ + public final void deployInfos(@Nullable Iterable infos, @Nullable GridCacheContext cctx) + throws IgniteCheckedException { + if (cctx != null) + deployInfos(infos, cctx.shared(), cctx.cacheObjectContext()); } /** @@ -335,32 +308,13 @@ protected final void unmarshalInfo(GridCacheEntryInfo info, GridCacheContext ctx * @param ctx Context. * @throws IgniteCheckedException If failed. */ - protected final void marshalInfos( - Iterable infos, - GridCacheSharedContext ctx, - CacheObjectContext cacheObjCtx - ) throws IgniteCheckedException { - assert ctx != null; - - if (infos != null) - for (GridCacheEntryInfo e : infos) - marshalInfo(e, ctx, cacheObjCtx); - } - - /** - * @param infos Entries to unmarshal. - * @param ctx Context. - * @param ldr Loader. - * @throws IgniteCheckedException If failed. - */ - protected final void unmarshalInfos(Iterable infos, - GridCacheContext ctx, ClassLoader ldr) throws IgniteCheckedException { - assert ldr != null; + final void deployInfos(Iterable infos, GridCacheSharedContext ctx, + CacheObjectContext cacheObjCtx) throws IgniteCheckedException { assert ctx != null; if (infos != null) for (GridCacheEntryInfo e : infos) - unmarshalInfo(e, ctx, ldr); + deployInfo(e, ctx, cacheObjCtx); } /** @@ -368,29 +322,26 @@ protected final void unmarshalInfos(Iterable infos * @param ctx Context. * @throws IgniteCheckedException If failed. */ - protected final void marshalTx(Iterable txEntries, GridCacheSharedContext ctx) + public final void deployTx(Iterable txEntries, GridCacheSharedContext ctx) throws IgniteCheckedException { assert ctx != null; if (txEntries != null) { - boolean transferExpiry = transferExpiryPolicy(); boolean p2pEnabled = ctx.deploymentEnabled(); for (IgniteTxEntry e : txEntries) { - e.marshal(ctx, transferExpiry); - GridCacheContext cctx = e.context(); if (addDepInfo) { if (e.key() != null) - prepareObject(e.key().value(cctx.cacheObjectContext(), false), ctx); + deployObject(e.key().value(cctx.cacheObjectContext(), false), ctx); if (e.value() != null) - prepareObject(e.value().value(cctx.cacheObjectContext(), false), ctx); + deployObject(e.value().value(cctx.cacheObjectContext(), false), ctx); if (e.entryProcessors() != null) { for (T2, Object[]> entProc : e.entryProcessors()) - prepareObject(entProc.get1(), ctx); + deployObject(entProc.get1(), ctx); } } else if (p2pEnabled && e.entryProcessors() != null) { @@ -398,134 +349,108 @@ else if (p2pEnabled && e.entryProcessors() != null) { forceAddDepInfo = true; for (T2, Object[]> entProc : e.entryProcessors()) - prepareObject(entProc.get1(), ctx); + deployObject(entProc.get1(), ctx); } } } } /** - * @return {@code True} if entries expire policy should be marshalled. - */ - protected boolean transferExpiryPolicy() { - return false; - } - - /** - * @param txEntries Entries to unmarshal. - * @param ctx Context. - * @param ldr Loader. + * @param args Arguments to marshal. + * @param marsh Marshaller. + * @return Marshalled collection. * @throws IgniteCheckedException If failed. */ - protected final void unmarshalTx(Iterable txEntries, - GridCacheSharedContext ctx, - ClassLoader ldr) throws IgniteCheckedException { - assert ldr != null; - assert ctx != null; + @Nullable protected final byte[][] marshallInvokeArguments(@Nullable Object[] args, Marshaller marsh) + throws IgniteCheckedException { - if (txEntries != null) { - for (IgniteTxEntry e : txEntries) { - e.prepareUnmarshal(ctx, topologyVersion(), false); + if (args == null || args.length == 0) + return null; - e.unmarshal(ctx, false, ldr); - } + byte[][] argsBytes = new byte[args.length][]; + + for (int i = 0; i < args.length; i++) { + Object arg = args[i]; + + argsBytes[i] = arg == null ? null : U.marshal(marsh, arg); } + + return argsBytes; } /** * @param args Arguments to marshal. * @param ctx Context. - * @return Marshalled collection. * @throws IgniteCheckedException If failed. */ - @Nullable protected final byte[][] marshalInvokeArguments(@Nullable Object[] args, GridCacheContext ctx) + public final void deployInvokeArguments(@Nullable Object[] args, @Nullable GridCacheContext ctx) throws IgniteCheckedException { - assert ctx != null; - - if (args == null || args.length == 0) - return null; - - byte[][] argsBytes = new byte[args.length][]; + if (ctx == null || args == null) + return; for (int i = 0; i < args.length; i++) { Object arg = args[i]; if (addDepInfo) - prepareObject(arg, ctx.shared()); - - argsBytes[i] = arg == null ? null : CU.marshal(ctx, arg); + deployObject(arg, ctx.shared()); } - - return argsBytes; } - /** * @param byteCol Collection to unmarshal. - * @param ctx Context. + * @param marsh Marshaller. * @param ldr Loader. * @return Unmarshalled collection. * @throws IgniteCheckedException If failed. */ @Nullable protected final Object[] unmarshalInvokeArguments(@Nullable byte[][] byteCol, - GridCacheSharedContext ctx, + Marshaller marsh, ClassLoader ldr) throws IgniteCheckedException { - assert ldr != null; - assert ctx != null; - if (byteCol == null) return null; Object[] args = new Object[byteCol.length]; - Marshaller marsh = ctx.marshaller(); - for (int i = 0; i < byteCol.length; i++) - args[i] = byteCol[i] == null ? null : U.unmarshal(marsh, byteCol[i], U.resolveClassLoader(ldr, ctx.gridConfig())); + args[i] = byteCol[i] == null ? null : U.unmarshal(marsh, byteCol[i], ldr); return args; } /** * @param col Collection to marshal. - * @param ctx Context. + * @param marsh Marshaller. * @return Marshalled collection. * @throws IgniteCheckedException If failed. */ - @Nullable protected List marshalCollection(@Nullable Collection col, - GridCacheContext ctx) throws IgniteCheckedException { - assert ctx != null; - + @Nullable protected List marshallCollection(@Nullable Collection col, Marshaller marsh) throws IgniteCheckedException { if (col == null) return null; List byteCol = new ArrayList<>(col.size()); - for (Object o : col) { - if (addDepInfo) - prepareObject(o, ctx.shared()); - - byteCol.add(o == null ? null : CU.marshal(ctx, o)); - } + for (Object o : col) + byteCol.add(o == null ? null : U.marshal(marsh, o)); return byteCol; } /** - * @param col Collection. - * @param ctx Cache context. + * Deploys each element of {@code col} via {@link #deployObject} on each item. + * + * @param col Collection to marshal. + * @param ctx Context. * @throws IgniteCheckedException If failed. */ - @SuppressWarnings("ForLoopReplaceableByForEach") - public final void prepareMarshalCacheObjects(@Nullable List col, - GridCacheContext ctx) throws IgniteCheckedException { - if (col == null) + public final void deployCollection(@Nullable Collection col, + @Nullable GridCacheContext ctx) throws IgniteCheckedException { + if (ctx == null || col == null) return; - int size = col.size(); - - for (int i = 0; i < size; i++) - prepareMarshalCacheObject(col.get(i), ctx); + for (Object o : col) { + if (addDepInfo) + deployObject(o, ctx.shared()); + } } /** @@ -533,13 +458,9 @@ public final void prepareMarshalCacheObjects(@Nullable List col, - GridCacheContext ctx) throws IgniteCheckedException { - if (col == null) + public final void deployCacheObjects(@Nullable Collection col, + @Nullable GridCacheContext ctx) throws IgniteCheckedException { + if (col == null || ctx == null) return; for (CacheObject obj : col) { if (obj != null) { - obj.prepareMarshal(ctx.cacheObjectContext()); - if (addDepInfo) - prepareObject(obj.value(ctx.cacheObjectContext(), false), ctx.shared()); + deployObject(obj.value(ctx.cacheObjectContext(), false), ctx.shared()); } } } - /** - * @param col Collection. - * @param ctx Context. - * @param ldr Class loader. - * @throws IgniteCheckedException If failed. - */ - @SuppressWarnings("ForLoopReplaceableByForEach") - public final void finishUnmarshalCacheObjects(@Nullable List col, - GridCacheContext ctx, - ClassLoader ldr - ) throws IgniteCheckedException { - if (col == null) - return; - - int size = col.size(); - - for (int i = 0; i < size; i++) { - CacheObject obj = col.get(i); - - if (obj != null) - obj.finishUnmarshal(ctx.cacheObjectContext(), ldr); - } - } - - /** - * @param col Collection. - * @param ctx Context. - * @param ldr Class loader. - * @throws IgniteCheckedException If failed. - */ - protected final void finishUnmarshalCacheObjects(@Nullable Collection col, - GridCacheContext ctx, - ClassLoader ldr - ) throws IgniteCheckedException { - if (col == null) - return; - - for (CacheObject obj : col) { - if (obj != null) - obj.finishUnmarshal(ctx.cacheObjectContext(), ldr); - } - } - /** * @param byteCol Collection to unmarshal. - * @param ctx Context. + * @param marsh Marshaller. * @param ldr Loader. * @return Unmarshalled collection. * @throws IgniteCheckedException If failed. */ @Nullable protected List unmarshalCollection(@Nullable Collection byteCol, - GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - assert ldr != null; - assert ctx != null; - + Marshaller marsh, ClassLoader ldr) throws IgniteCheckedException { if (byteCol == null) return null; List col = new ArrayList<>(byteCol.size()); - Marshaller marsh = ctx.marshaller(); - for (byte[] bytes : byteCol) - col.add(bytes == null ? null : U.unmarshal(marsh, bytes, U.resolveClassLoader(ldr, ctx.gridConfig()))); + col.add(bytes == null ? null : U.unmarshal(marsh, bytes, ldr)); return col; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessageDeployer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessageDeployer.java new file mode 100644 index 0000000000000..570802a198675 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessageDeployer.java @@ -0,0 +1,51 @@ +/* + * 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.cache; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.plugin.extensions.communication.MessageFactory; +import org.jetbrains.annotations.Nullable; + +/** + * Per-message deployer. A generated {@code Deployer} implements {@link #deploy(GridCacheMessage, GridCacheSharedContext)} + * to deploy the message's fields (via {@code GridCacheMessage}'s public {@code deploy*} methods). The static + * {@link #deploy(MessageFactory, GridCacheMessage, GridCacheSharedContext)} is the factory-resolving entry point, + * mirroring the static {@code MessageMarshaller#marshal}. + */ +public interface GridCacheMessageDeployer { + /** Deploys all deployable fields of {@code msg}. */ + void deploy(M msg, GridCacheSharedContext ctx) throws IgniteCheckedException; + + /** + * Deploys {@code msg} through its factory-registered deployer (a no-op when {@code msg} is + * {@code null} — e.g. an absent nested message — or the message has no registered deployer). Single entry point + * for message deployment: called both by message-sending code and by a generated deployer delegating to a nested + * message. Mirrors the static {@code MessageMarshaller#marshal}. + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + static void deploy(MessageFactory factory, @Nullable GridCacheMessage msg, GridCacheSharedContext ctx) + throws IgniteCheckedException { + if (msg == null) + return; + + GridCacheMessageDeployer deployer = factory.deployer(msg.directType()); + + if (deployer != null) + deployer.deploy(msg, ctx); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheReturn.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheReturn.java index 7c78a10a5cf48..a98d9b0e24158 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheReturn.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheReturn.java @@ -22,7 +22,6 @@ import java.util.HashMap; import java.util.Map; import javax.cache.processor.EntryProcessorResult; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.UnregisteredBinaryTypeException; @@ -31,13 +30,14 @@ import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.extensions.communication.CacheIdAware; import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; /** * Return value for cases where both, value and success flag need to be returned. */ -public class GridCacheReturn implements Message { +public class GridCacheReturn implements Message, CacheIdAware { /** Value. */ @GridToStringInclude(sensitive = true) private volatile Object v; @@ -121,7 +121,26 @@ public GridCacheReturn( /** * @return Value. */ - @Nullable public V value() { + @Nullable public V value(GridCacheContext ctx) { + if (v == null) { + if (cacheObj != null) + v = ctx.cacheObjectContext().unwrapBinaryIfNeeded(cacheObj, true, false, ctx.deploy().globalLoader()); + + if (invokeRes && invokeResCol != null) { + Map map0 = U.newHashMap(invokeResCol.size()); + + for (CacheInvokeDirectResult res : invokeResCol) { + CacheInvokeResult res0 = res.error() == null ? + CacheInvokeResult.fromResult(ctx.cacheObjectContext().unwrapBinaryIfNeeded(res.result(), true, false, null)) : + CacheInvokeResult.fromError(res.error()); + + map0.put(ctx.cacheObjectContext().unwrapBinaryIfNeeded(res.key(), true, false, null), res0); + } + + v = map0; + } + } + return (V)v; } @@ -285,22 +304,20 @@ else if (err instanceof UnregisteredBinaryTypeException) } } - /** - * @return Cache ID. - */ - public int cacheId() { + /** {@inheritDoc} */ + @Override public int cacheId() { return cacheId; } /** * @param other Other result to merge with. */ - public synchronized void mergeEntryProcessResults(GridCacheReturn other) { + public synchronized void mergeEntryProcessResults(GridCacheContext ctx, GridCacheReturn other) { assert invokeRes || v == null : "Invalid state to merge: " + this; assert other.invokeRes; assert loc == other.loc : loc; - if (other.v == null) + if (other.value(ctx) == null) return; invokeRes = true; @@ -328,55 +345,6 @@ public void marshalResult(GridCacheContext ctx) { } } - /** - * @param ctx Cache context. - * @throws IgniteCheckedException If failed. - */ - public void prepareMarshal(GridCacheContext ctx) throws IgniteCheckedException { - assert !loc; - - if (cacheObj != null) - cacheObj.prepareMarshal(ctx.cacheObjectContext()); - - if (invokeRes && invokeResCol != null) { - for (CacheInvokeDirectResult res : invokeResCol) - res.prepareMarshal(ctx); - } - } - - /** - * @param ctx Cache context. - * @param ldr Class loader. - * @throws IgniteCheckedException If failed. - */ - public void finishUnmarshal(GridCacheContext ctx, ClassLoader ldr) throws IgniteCheckedException { - loc = true; - - if (cacheObj != null) { - cacheObj.finishUnmarshal(ctx.cacheObjectContext(), ldr); - - v = ctx.cacheObjectContext().unwrapBinaryIfNeeded(cacheObj, true, false, ldr); - } - - if (invokeRes && invokeResCol != null) { - for (CacheInvokeDirectResult res : invokeResCol) - res.finishUnmarshal(ctx, ldr); - - Map map0 = U.newHashMap(invokeResCol.size()); - - for (CacheInvokeDirectResult res : invokeResCol) { - CacheInvokeResult res0 = res.error() == null ? - CacheInvokeResult.fromResult(ctx.cacheObjectContext().unwrapBinaryIfNeeded(res.result(), true, false, null)) : - CacheInvokeResult.fromError(res.error()); - - map0.put(ctx.cacheObjectContext().unwrapBinaryIfNeeded(res.key(), true, false, null), res0); - } - - v = map0; - } - } - - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridCacheReturn.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java index 48a3328d0469b..c97aefd68213f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java @@ -995,13 +995,19 @@ private long allocateForTree() throws IgniteCheckedException { assert info.ttl() == TTL_ETERNAL : info.ttl(); - batch.add(new DataRowCacheAware(info.key(), - info.value(), - info.version(), - part.id(), - info.expireTime(), - info.cacheId(), - grp.storeCacheIdInDataPage())); + try { + batch.add(new DataRowCacheAware(info.key(), + info.value(), + info.version(), + part.id(), + info.expireTime(), info.cacheId(), grp.storeCacheIdInDataPage())); + } + catch (IllegalStateException th) { + if (ctx.cacheContext(info.cacheId()) != null) + throw th; // Not a removed-cache race — propagate. + + // Ignoring removed cache entries. + } if (batch.size() == PRELOAD_SIZE_UNDER_CHECKPOINT_LOCK || !infos.hasNext()) { ctx.database().checkpointReadLock(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheObjectImpl.java index f781fb3218b42..721eb3d813994 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheObjectImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/KeyCacheObjectImpl.java @@ -108,19 +108,20 @@ public KeyCacheObjectImpl(Object val, byte[] valBytes, int part) { /** {@inheritDoc} */ @Override public int hashCode() { - assert val != null; + if (val == null) + throw new CacheObjectNotResolvedException(); return IgniteUtils.hashCode(val); } /** {@inheritDoc} */ - @Override public void prepareMarshal(CacheObjectValueContext ctx) throws IgniteCheckedException { + @Override public void marshal(CacheObjectValueContext ctx) throws IgniteCheckedException { if (valBytes == null) valBytes = ctx.marshal(val); } /** {@inheritDoc} */ - @Override public void finishUnmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { + @Override public void unmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { if (val == null) { assert valBytes != null; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/StoredCacheData.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/StoredCacheData.java index dc94809a9446c..415bd5f890fc8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/StoredCacheData.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/StoredCacheData.java @@ -19,11 +19,10 @@ import java.io.Serializable; import java.util.Collection; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.QueryEntity; import org.apache.ignite.cdc.CdcCacheEvent; import org.apache.ignite.configuration.CacheConfiguration; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.encryption.GroupKeyEncrypted; import org.apache.ignite.internal.pagemem.store.IgnitePageStoreManager; @@ -32,9 +31,8 @@ import org.apache.ignite.internal.util.typedef.internal.A; import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.marshaller.jdk.JdkMarshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; /** @@ -45,13 +43,14 @@ *

* All changes must be made with the respect of RU rules. */ -public class StoredCacheData implements Serializable, CdcCacheEvent, MarshallableMessage { +public class StoredCacheData implements Serializable, CdcCacheEvent, Message { /** */ private static final long serialVersionUID = 0L; /** Cache configuration. */ @GridToStringInclude - private CacheConfiguration ccfg; + @Marshalled("ccfgBytes") + CacheConfiguration ccfg; /** Serialized {@link #ccfg}. */ @Order(0) @@ -59,7 +58,8 @@ public class StoredCacheData implements Serializable, CdcCacheEvent, Marshallabl /** Query entities. */ @GridToStringInclude - private Collection qryEntities; + @Marshalled("qryEntitiesBytes") + Collection qryEntities; /** Serialized {@link #qryEntities}. */ @Order(1) @@ -224,27 +224,4 @@ public StoredCacheData withSplittedCacheConfig(CacheConfigurationSplitter splitt return ccfg; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (ccfg != null) - ccfgBytes = U.marshal(marsh, ccfg); - - if (qryEntities != null) - qryEntitiesBytes = U.marshal(marsh, qryEntities); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - if (ccfgBytes != null) { - ccfg = U.unmarshal(marsh, ccfgBytes, clsLdr); - - ccfgBytes = null; - } - - if (qryEntitiesBytes != null) { - qryEntities = U.unmarshal(marsh, qryEntitiesBytes, clsLdr); - - qryEntitiesBytes = null; - } - } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataVersionInfo.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataVersionInfo.java index 9fe6d19da4421..ca112d9f8777c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataVersionInfo.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataVersionInfo.java @@ -17,12 +17,10 @@ package org.apache.ignite.internal.processors.cache.binary; import java.io.Serializable; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.binary.BinaryMetadata; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; /** * Wrapper for {@link BinaryMetadata} which is stored in metadata local cache on each node. @@ -30,12 +28,13 @@ * The version refers solely to the internal protocol for updating BinaryMetadata and is unknown externally. * It can be updated dynamically from different nodes and threads on the same node. */ -public final class BinaryMetadataVersionInfo implements Serializable, MarshallableMessage { +public final class BinaryMetadataVersionInfo implements Serializable, Message { /** */ private static final long serialVersionUID = 0L; /** The actual binary metadata. */ - private BinaryMetadata metadata; + @Marshalled("metadataBytes") + BinaryMetadata metadata; /** Serialized binary metadata. */ @Order(0) @@ -129,22 +128,6 @@ boolean removing() { return removing; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (metadata != null) - metadataBytes = U.marshal(marsh, metadata); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - if (metadataBytes != null) { - metadata = U.unmarshal(marsh, metadataBytes, clsLdr); - - // It is not required anymore. - metadataBytes = null; - } - } - /** {@inheritDoc} */ @Override public String toString() { return "[typeId=" + metadata.typeId() + diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/MetadataUpdateProposedMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/MetadataUpdateProposedMessage.java index 90820675c6252..cdef7dbb27e8f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/MetadataUpdateProposedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/MetadataUpdateProposedMessage.java @@ -17,18 +17,16 @@ package org.apache.ignite.internal.processors.cache.binary; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.binary.BinaryObjectException; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.binary.BinaryMetadata; import org.apache.ignite.internal.binary.BinaryMetadataHandler; import org.apache.ignite.internal.managers.communication.ErrorMessage; import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; /** @@ -73,13 +71,14 @@ * it gets blocked until {@link MetadataUpdateAcceptedMessage} arrives with accepted version * equals to pending version of this metadata to the moment when is was initially read by the thread. */ -public final class MetadataUpdateProposedMessage extends DiscoveryCustomMessage implements MarshallableMessage { +public final class MetadataUpdateProposedMessage extends DiscoveryCustomMessage implements Message { /** Node UUID which initiated metadata update. */ @Order(0) UUID origNodeId; /** */ - private BinaryMetadata metadata; + @Marshalled("metadataBytes") + BinaryMetadata metadata; /** Serialized {@link #metadata}. */ @Order(1) @@ -184,6 +183,10 @@ public BinaryMetadata metadata() { /** @param metadata Metadata. */ public void metadata(BinaryMetadata metadata) { this.metadata = metadata; + + // Invalidate the cached marshalled form so a re-marshal (e.g. coordinator re-propagating merged metadata) + // picks up the new value instead of keeping the stale bytes under the marshal-once guard. + this.metadataBytes = null; } /** */ @@ -191,18 +194,6 @@ public int typeId() { return typeId; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (metadata != null) - metadataBytes = U.marshal(marsh, metadata); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader ldr) throws IgniteCheckedException { - if (metadataBytes != null) - metadata = U.unmarshal(marsh, metadataBytes, ldr); - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(MetadataUpdateProposedMessage.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTtlUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTtlUpdateRequest.java index c83e732f6181a..306b2f6d90181 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTtlUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTtlUpdateRequest.java @@ -19,12 +19,9 @@ import java.util.ArrayList; import java.util.List; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -155,35 +152,11 @@ public List nearVersions() { return nearVers; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(keys, cctx); - - prepareMarshalCacheObjects(nearKeys, cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) - throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(keys, cctx, ldr); - - finishUnmarshalCacheObjects(nearKeys, cctx, ldr); - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return false; } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridCacheTtlUpdateRequest.class, this, "super", super.toString()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java index 82875ddab682d..a488669cb0db5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java @@ -20,10 +20,8 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; @@ -382,26 +380,6 @@ public long timeout() { return ctx.txLockMessageLogger(); } - /** {@inheritDoc} - * @param ctx*/ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(keys, cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(keys, cctx, ldr); - } - - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridDistributedLockRequest.class, this, "keysCnt", retVals.length, diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java index cbf10745a7a19..04a4c67b5a89c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.List; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.communication.ErrorMessage; @@ -159,22 +158,6 @@ protected int valuesSize() { return ctx.txLockMessageLogger(); } - /** {@inheritDoc} - * @param ctx*/ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - prepareMarshalCacheObjects(vals, ctx.cacheContext(cacheId)); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - finishUnmarshalCacheObjects(vals, ctx.cacheContext(cacheId), ldr); - } - - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridDistributedLockResponse.class, this, diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java index 68a53ca1936bc..5f9b018372f08 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java @@ -20,13 +20,11 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; +import org.apache.ignite.internal.MarshalledMap; import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry; @@ -37,7 +35,6 @@ import org.apache.ignite.internal.util.tostring.GridToStringBuilder; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.transactions.TransactionConcurrency; import org.apache.ignite.transactions.TransactionIsolation; import org.jetbrains.annotations.Nullable; @@ -102,7 +99,8 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage /** DHT versions to verify. */ @GridToStringInclude - private Map dhtVers; + @MarshalledMap(keys = "dhtVerKeys", values = "dhtVerVals") + Map dhtVers; /** */ @Order(7) @@ -371,57 +369,6 @@ public void applicationAttributes(Map appAttrs) { this.txState = txState; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (writes != null) - marshalTx(writes, ctx); - - if (reads != null) - marshalTx(reads, ctx); - - if (dhtVers != null && dhtVerKeys == null) { - for (IgniteTxKey key : dhtVers.keySet()) { - GridCacheContext cctx = ctx.cacheContext(key.cacheId()); - - key.prepareMarshal(cctx); - } - - dhtVerKeys = dhtVers.keySet(); - dhtVerVals = dhtVers.values(); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (writes != null) - unmarshalTx(writes, ctx, ldr); - - if (reads != null) - unmarshalTx(reads, ctx, ldr); - - if (dhtVerKeys != null && dhtVers == null) { - assert dhtVerVals != null; - assert dhtVerKeys.size() == dhtVerVals.size(); - - Iterator keyIt = dhtVerKeys.iterator(); - Iterator verIt = dhtVerVals.iterator(); - - dhtVers = U.newHashMap(dhtVerKeys.size()); - - while (keyIt.hasNext()) { - IgniteTxKey key = keyIt.next(); - - key.finishUnmarshal(ctx.cacheContext(key.cacheId()), ldr); - - dhtVers.put(key, verIt.next()); - } - } - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return addDepInfo || forceAddDepInfo; @@ -452,7 +399,6 @@ private boolean isFlag(int mask) { return (flags & mask) != 0; } - /** {@inheritDoc} */ @Override public String toString() { StringBuilder flags = new StringBuilder(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridNearUnlockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridNearUnlockRequest.java index 7f46f96774850..268b923232f0c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridNearUnlockRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridNearUnlockRequest.java @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.List; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; @@ -93,27 +92,11 @@ public void addKey(KeyCacheObject key) { return keys != null && !keys.isEmpty() ? keys.get(0).partition() : -1; } - /** {@inheritDoc} - * @param ctx*/ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - prepareMarshalCacheObjects(keys, ctx.cacheContext(cacheId)); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - finishUnmarshalCacheObjects(keys, ctx.cacheContext(cacheId), ldr); - } - /** {@inheritDoc} */ @Override public IgniteLogger messageLogger(GridCacheSharedContext ctx) { return ctx.txLockMessageLogger(); } - - + /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridNearUnlockRequest.class, this, "super", super.toString()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java index 7277db3ccd698..ec2e09483c0d1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java @@ -1214,9 +1214,9 @@ protected void processNearSingleGetRequest(final UUID nodeId, final GridNearSing res0 = info; } else if (req.needVersion()) - res0 = new CacheVersionedValue(info.value(), info.version()); + res0 = new CacheVersionedValue(info.value(), info.version(), info.cacheId()); else - res0 = new CacheVersionedValue(info.value(), null); + res0 = new CacheVersionedValue(info.value(), null, info.cacheId()); } res = new GridNearSingleGetResponse( diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java index 0f2e50892fb08..588861c03bde2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java @@ -1032,9 +1032,6 @@ private void map(Iterable entries) { } assert added.dhtLocal(); - - if (added.ownerVersion() != null) - req.owned(e.key(), added.ownerVersion()); } catch (GridCacheEntryRemovedException ex) { if (log.isDebugEnabled()) { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java index 0c51befe57960..3d20269b8d91c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java @@ -18,18 +18,12 @@ package org.apache.ignite.internal.processors.cache.distributed.dht; import java.util.BitSet; -import java.util.Map; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockRequest; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.GridLeanMap; -import org.apache.ignite.internal.util.tostring.GridToStringExclude; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.transactions.TransactionIsolation; @@ -48,38 +42,24 @@ public class GridDhtLockRequest extends GridDistributedLockRequest { @Order(1) IgniteUuid miniId; - /** Owner mapped version, if any. */ - @GridToStringInclude - private Map owned; - - /** Array of keys from {@link #owned}. Used during marshalling and unmarshalling. */ - @Order(2) - @GridToStringExclude - KeyCacheObject[] ownedKeys; - - /** Array of values from {@link #owned}. Used during marshalling and unmarshalling. */ - @Order(3) - @GridToStringExclude - GridCacheVersion[] ownedValues; - /** Topology version. */ - @Order(4) + @Order(2) AffinityTopologyVersion topVer; /** Task name hash. */ - @Order(5) + @Order(3) int taskNameHash; /** Indexes of keys needed to be preloaded. */ - @Order(6) + @Order(4) BitSet preloadKeys; /** TTL for read operation. */ - @Order(7) + @Order(5) long accessTtl; /** Transaction label. */ - @Order(8) + @Order(6) String txLbl; /** @@ -218,19 +198,6 @@ public boolean needPreloadKey(int idx) { return preloadKeys != null && preloadKeys.get(idx); } - /** - * Sets owner and its mapped version. - * - * @param key Key. - * @param ownerMapped Owner mapped version. - */ - public void owned(KeyCacheObject key, GridCacheVersion ownerMapped) { - if (owned == null) - owned = new GridLeanMap<>(3); - - owned.put(key, ownerMapped); - } - /** * @param idx Entry index to check. * @return {@code True} if near entry should be invalidated. @@ -260,42 +227,6 @@ public long accessTtl() { return txLbl; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (owned != null && ownedKeys == null) { - ownedKeys = new KeyCacheObject[owned.size()]; - ownedValues = new GridCacheVersion[ownedKeys.length]; - - int i = 0; - - for (Map.Entry entry : owned.entrySet()) { - ownedKeys[i] = entry.getKey(); - ownedValues[i] = entry.getValue(); - i++; - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (ownedKeys != null) { - owned = new GridLeanMap<>(ownedKeys.length); - - for (int i = 0; i < ownedKeys.length; i++) { - ownedKeys[i].finishUnmarshal(ctx.cacheContext(cacheId).cacheObjectContext(), ldr); - owned.put(ownedKeys[i], ownedValues[i]); - } - - ownedKeys = null; - ownedValues = null; - } - } - - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridDhtLockRequest.class, this, "super", super.toString()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java index e73f606c827eb..cf0b9b0680113 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java @@ -23,6 +23,7 @@ import java.util.List; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.processors.cache.DeployableMessage; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; @@ -36,7 +37,7 @@ * DHT cache lock response. */ @SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType") -public class GridDhtLockResponse extends GridDistributedLockResponse { +public class GridDhtLockResponse extends GridDistributedLockResponse implements DeployableMessage { /** Mini future ID. */ @Order(0) IgniteUuid miniId; @@ -124,24 +125,14 @@ public Collection preloadEntries() { } /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); + @Override public void deploy(GridCacheSharedContext ctx) throws IgniteCheckedException { + if (preloadEntries != null) { + GridCacheContext cctx = ctx.cacheContext(cacheId); - GridCacheContext cctx = ctx.cacheContext(cacheId); - - if (preloadEntries != null) - marshalInfos(preloadEntries, cctx.shared(), cctx.cacheObjectContext()); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (preloadEntries != null) - unmarshalInfos(preloadEntries, ctx.cacheContext(cacheId), ldr); + deployInfos(preloadEntries, cctx); + } } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridDhtLockResponse.class, this, super.toString()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java index 352281f9b57c8..62c327c8d7ce5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java @@ -17,12 +17,9 @@ package org.apache.ignite.internal.processors.cache.distributed.dht; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.communication.ErrorMessage; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheReturn; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxFinishResponse; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.typedef.internal.S; @@ -118,33 +115,6 @@ public boolean checkCommitted() { return checkCommitted; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (retVal != null && retVal.cacheId() != 0) { - GridCacheContext cctx = ctx.cacheContext(retVal.cacheId()); - - assert cctx != null : retVal.cacheId(); - - retVal.prepareMarshal(cctx); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) - throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (retVal != null && retVal.cacheId() != 0) { - GridCacheContext cctx = ctx.cacheContext(retVal.cacheId()); - - assert cctx != null : retVal.cacheId(); - - retVal.finishUnmarshal(cctx, ldr); - } - } - /** * @param retVal Return value. */ @@ -158,8 +128,7 @@ public void returnValue(GridCacheReturn retVal) { public GridCacheReturn returnValue() { return retVal; } - - + /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridDhtTxFinishResponse.class, this, "super", super.toString()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java index 4c7e9313f5e16..74140402ca968 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java @@ -496,7 +496,7 @@ private void addMapping( assert state == PREPARING : "Invalid tx state for " + "adding entry [msgId=" + msgId + ", e=" + e + ", tx=" + this + ']'; - e.unmarshal(cctx, false, cctx.deploy().globalLoader()); + e.initializeContext(cctx, topVer, false); checkInternal(e.txKey()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java index f8364dca6adb1..2efa19a6677e3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java @@ -17,17 +17,16 @@ package org.apache.ignite.internal.processors.cache.distributed.dht; -import java.util.ArrayList; import java.util.BitSet; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.UUID; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.MarshalledMap; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.DeployableMessage; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxPrepareRequest; @@ -44,7 +43,7 @@ /** * DHT prepare request. */ -public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest { +public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest implements DeployableMessage { /** Max order. */ @Order(0) UUID nearNodeId; @@ -72,7 +71,8 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest { /** Owned versions by key. */ @GridToStringInclude - private Map owned; + @MarshalledMap(keys = "ownedKeys", values = "ownedVals") + Map owned; /** Owned keys. */ @Order(6) @@ -98,9 +98,6 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest { @Order(11) BitSet preloadKeys; - /** */ - private List nearWritesCacheMissed; - /** {@code True} if remote tx should skip adding itself to completed versions map on finish. */ @Order(12) boolean skipCompletedVers; @@ -187,13 +184,6 @@ public Collection updateCounters() { return updCntrs; } - /** - * @return Near cache writes for which cache was not found (possible if client near cache was closed). - */ - @Nullable public List nearWritesCacheMissed() { - return nearWritesCacheMissed; - } - /** * @return Near transaction ID. */ @@ -315,83 +305,18 @@ public boolean skipCompletedVersion() { return txLbl; } - /** - * {@inheritDoc} - * - * @param ctx - */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - + /** {@inheritDoc} */ + @Override public void deploy(GridCacheSharedContext ctx) throws IgniteCheckedException { if (owned != null && ownedKeys == null) { - ownedKeys = owned.keySet(); - - ownedVals = owned.values(); - - for (IgniteTxKey key: ownedKeys) { + for (IgniteTxKey key : owned.keySet()) { GridCacheContext cctx = ctx.cacheContext(key.cacheId()); - key.prepareMarshal(cctx); - if (addDepInfo) - prepareObject(key, cctx); + deployObject(key, cctx); } } - - if (nearWrites != null) - marshalTx(nearWrites, ctx); } - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (ownedKeys != null) { - assert ownedKeys.size() == ownedVals.size(); - - owned = U.newHashMap(ownedKeys.size()); - - Iterator keyIter = ownedKeys.iterator(); - - Iterator valIter = ownedVals.iterator(); - - while (keyIter.hasNext()) { - IgniteTxKey key = keyIter.next(); - - GridCacheContext cacheCtx = ctx.cacheContext(key.cacheId()); - - if (cacheCtx != null) { - key.finishUnmarshal(cacheCtx, ldr); - - owned.put(key, valIter.next()); - } - } - } - - if (nearWrites != null) { - for (Iterator it = nearWrites.iterator(); it.hasNext();) { - IgniteTxEntry e = it.next(); - - GridCacheContext cacheCtx = ctx.cacheContext(e.cacheId()); - - if (cacheCtx == null) { - it.remove(); - - if (nearWritesCacheMissed == null) - nearWritesCacheMissed = new ArrayList<>(); - - nearWritesCacheMissed.add(e.txKey()); - } - else { - e.context(cacheCtx); - - e.unmarshal(ctx, true, ldr); - } - } - } - } - - /** {@inheritDoc} */ @Override public int partition() { return U.safeAbs(version().hashCode()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java index 921f52790252b..f4ad3faa6bd50 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java @@ -21,11 +21,8 @@ import java.util.Collection; import java.util.List; import java.util.Map; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxPrepareResponse; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; @@ -169,51 +166,6 @@ public void addPreloadEntry(GridCacheEntryInfo info) { preloadEntries.add(info); } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (nearEvicted != null) { - for (IgniteTxKey key : nearEvicted) { - GridCacheContext cctx = ctx.cacheContext(key.cacheId()); - - // Can be null if client near cache was removed, in this case assume do not need prepareMarshal. - if (cctx != null) - key.prepareMarshal(cctx); - } - } - - if (preloadEntries != null) { - for (GridCacheEntryInfo info : preloadEntries) { - GridCacheContext cctx = ctx.cacheContext(info.cacheId()); - - info.marshal(cctx); - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (nearEvicted != null) { - for (IgniteTxKey key : nearEvicted) { - GridCacheContext cctx = ctx.cacheContext(key.cacheId()); - - key.finishUnmarshal(cctx, ldr); - } - } - - if (preloadEntries != null) { - for (GridCacheEntryInfo info : preloadEntries) { - GridCacheContext cctx = ctx.cacheContext(info.cacheId()); - - info.unmarshal(cctx, ldr); - } - } - } - - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridDhtTxPrepareResponse.class, this, diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java index c2ad54b41b910..de6676f8f138c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java @@ -271,7 +271,7 @@ public UUID nearNodeId() { * @throws IgniteCheckedException If failed. */ public void addWrite(IgniteTxEntry entry, ClassLoader ldr) throws IgniteCheckedException { - entry.unmarshal(cctx, false, ldr); + entry.initializeContext(cctx, topVer, false); GridCacheContext cacheCtx = entry.context(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtUnlockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtUnlockRequest.java index 8c5fc051a69e7..609e319171a3e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtUnlockRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtUnlockRequest.java @@ -21,7 +21,6 @@ import java.util.List; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.distributed.GridNearUnlockRequest; import org.apache.ignite.internal.util.typedef.internal.S; @@ -70,20 +69,6 @@ public void addNearKey(KeyCacheObject key) nearKeys.add(key); } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - prepareMarshalCacheObjects(nearKeys, ctx.cacheContext(cacheId)); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - finishUnmarshalCacheObjects(nearKeys, ctx.cacheContext(cacheId), ldr); - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridDhtUnlockRequest.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/TransactionAttributesAwareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/TransactionAttributesAwareRequest.java index 4cc026c390cda..e24d5c0d41816 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/TransactionAttributesAwareRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/TransactionAttributesAwareRequest.java @@ -18,10 +18,8 @@ package org.apache.ignite.internal.processors.cache.distributed.dht; import java.util.Map; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.GridCacheMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxPrepareRequest; /** Wraps transaction prepare request with application attributes. */ @@ -57,16 +55,6 @@ public Map applicationAttributes() { return appAttrs; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - payload.prepareMarshal(ctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - payload.finishUnmarshal(ctx, ldr); - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return false; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/AtomicApplicationAttributesAwareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/AtomicApplicationAttributesAwareRequest.java index 7c37b474dd2b7..49bdc531a3049 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/AtomicApplicationAttributesAwareRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/AtomicApplicationAttributesAwareRequest.java @@ -18,10 +18,8 @@ package org.apache.ignite.internal.processors.cache.distributed.dht.atomic; import java.util.Map; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; /** Wraps atomic updates with application attributes. */ public class AtomicApplicationAttributesAwareRequest extends GridCacheIdMessage { @@ -57,16 +55,6 @@ public Map applicationAttributes() { return appAttrs; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - payload.prepareMarshal(ctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - payload.finishUnmarshal(ctx, ldr); - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return false; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicNearResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicNearResponse.java index f71e035bdac94..f7944ca52288c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicNearResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicNearResponse.java @@ -18,11 +18,9 @@ package org.apache.ignite.internal.processors.cache.distributed.dht.atomic; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; import org.apache.ignite.internal.processors.cache.GridCacheReturn; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -171,22 +169,6 @@ public long futureId() { return false; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (errs != null) - errs.prepareMarshal(this, ctx.cacheContext(cacheId)); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (errs != null) - errs.finishUnmarshal(this, ctx.cacheContext(cacheId), ldr); - } - /** {@inheritDoc} */ @Override public String toString() { StringBuilder flags = new StringBuilder(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java index 59988a5610ed1..667fb0dd0d752 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicSingleUpdateRequest.java @@ -19,13 +19,10 @@ import java.util.UUID; import javax.cache.processor.EntryProcessor; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheOperation; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -314,54 +311,6 @@ private void near(boolean near) { return null; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalObject(key, cctx); - - prepareMarshalObject(val, cctx); - - prepareMarshalObject(prevVal, cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalObject(key, cctx, ldr); - - finishUnmarshalObject(val, cctx, ldr); - - finishUnmarshalObject(prevVal, cctx, ldr); - } - - /** - * @param obj CacheObject to marshal - * @param ctx context - * @throws IgniteCheckedException if error - */ - private void prepareMarshalObject(CacheObject obj, GridCacheContext ctx) throws IgniteCheckedException { - if (obj != null) - obj.prepareMarshal(ctx.cacheObjectContext()); - } - - /** - * @param obj CacheObject un to marshal - * @param ctx context - * @param ldr class loader - * @throws IgniteCheckedException if error - */ - private void finishUnmarshalObject(@Nullable CacheObject obj, GridCacheContext ctx, - ClassLoader ldr) throws IgniteCheckedException { - if (obj != null) - obj.finishUnmarshal(ctx.cacheObjectContext(), ldr); - } - /** * Cleanup values not needed after message was sent. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java index 4f292290f627a..4e800386a1161 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java @@ -26,6 +26,7 @@ import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.DeployableMessage; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheOperation; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; @@ -36,13 +37,15 @@ import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * Lite dht cache backup update request. */ -public class GridDhtAtomicUpdateRequest extends GridDhtAtomicAbstractUpdateRequest { +public class GridDhtAtomicUpdateRequest extends GridDhtAtomicAbstractUpdateRequest implements MarshallableMessage, DeployableMessage { /** Keys to update. */ @GridToStringInclude @Order(0) @@ -98,14 +101,14 @@ public class GridDhtAtomicUpdateRequest extends GridDhtAtomicAbstractUpdateReque boolean forceTransformBackups; /** Entry processors. */ - private List> entryProcessors; + List> entryProcessors; /** Entry processors bytes. */ @Order(12) List entryProcessorsBytes; /** Near entry processors. */ - private List> nearEntryProcessors; + List> nearEntryProcessors; /** Near entry processors bytes. */ @Order(13) @@ -465,71 +468,56 @@ else if (conflictVers != null) } /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(keys, cctx); - - prepareMarshalCacheObjects(vals, cctx); - - prepareMarshalCacheObjects(nearKeys, cctx); - - prepareMarshalCacheObjects(nearVals, cctx); - - prepareMarshalCacheObjects(prevVals, cctx); + @Override protected void cleanup() { + nearVals = null; + prevVals = null; + } + /** {@inheritDoc} */ + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { if (forceTransformBackups) { - // force addition of deployment info for entry processors if P2P is enabled globally. - if (!addDepInfo && ctx.deploymentEnabled()) - addDepInfo = true; - if (!F.isEmpty(invokeArgs) && invokeArgsBytes == null) - invokeArgsBytes = Arrays.asList(marshalInvokeArguments(invokeArgs, cctx)); + invokeArgsBytes = Arrays.asList(marshallInvokeArguments(invokeArgs, marsh)); if (entryProcessorsBytes == null) - entryProcessorsBytes = marshalCollection(entryProcessors, cctx); + entryProcessorsBytes = marshallCollection(entryProcessors, marsh); if (nearEntryProcessorsBytes == null) - nearEntryProcessorsBytes = marshalCollection(nearEntryProcessors, cctx); + nearEntryProcessorsBytes = marshallCollection(nearEntryProcessors, marsh); } } /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(keys, cctx, ldr); - - finishUnmarshalCacheObjects(vals, cctx, ldr); - - finishUnmarshalCacheObjects(nearKeys, cctx, ldr); - - finishUnmarshalCacheObjects(nearVals, cctx, ldr); - - finishUnmarshalCacheObjects(prevVals, cctx, ldr); - + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (forceTransformBackups) { if (entryProcessors == null) - entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); + entryProcessors = unmarshalCollection(entryProcessorsBytes, marsh, clsLdr); if (invokeArgsBytes != null && invokeArgs == null) - invokeArgs = unmarshalInvokeArguments(invokeArgsBytes.toArray(new byte[invokeArgsBytes.size()][]), ctx, ldr); + invokeArgs = unmarshalInvokeArguments(invokeArgsBytes.toArray(new byte[invokeArgsBytes.size()][]), marsh, clsLdr); if (nearEntryProcessors == null) - nearEntryProcessors = unmarshalCollection(nearEntryProcessorsBytes, ctx, ldr); + nearEntryProcessors = unmarshalCollection(nearEntryProcessorsBytes, marsh, clsLdr); } } /** {@inheritDoc} */ - @Override protected void cleanup() { - nearVals = null; - prevVals = null; - } + @Override public void deploy(GridCacheSharedContext ctx) throws IgniteCheckedException { + if (forceTransformBackups) { + GridCacheContext cctx = ctx.cacheContext(cacheId); + forceDeploymentInfo(ctx); + + if (!F.isEmpty(invokeArgs) && invokeArgsBytes == null) + deployInvokeArguments(invokeArgs, cctx); + + if (entryProcessorsBytes == null) + deployCollection(entryProcessors, cctx); + + if (nearEntryProcessorsBytes == null) + deployCollection(nearEntryProcessors, cctx); + } + } /** {@inheritDoc} */ @Override public String toString() { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java index a63354bc634fa..451a3c26ae25d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java @@ -22,7 +22,6 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; @@ -118,33 +117,6 @@ public void nearEvicted(List nearEvicted) { return partId; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - // Can be null if client near cache was removed, in this case assume do not need prepareMarshal. - if (cctx != null) { - prepareMarshalCacheObjects(nearEvicted, cctx); - - if (errs != null) - errs.prepareMarshal(this, cctx); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(nearEvicted, cctx, ldr); - - if (errs != null) - errs.finishUnmarshal(this, cctx, ldr); - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return addDepInfo; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicAbstractUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicAbstractUpdateFuture.java index 21aa24e160865..d7638c11c8e5d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicAbstractUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicAbstractUpdateFuture.java @@ -365,7 +365,7 @@ final void completeFuture(@Nullable GridCacheReturn ret, Throwable err, @Nullabl ? null : (this.retval || op == TRANSFORM) ? cctx.unwrapBinaryIfNeeded( - ret.value(), + ret.value(cctx), keepBinary, U.deploymentClassLoader(cctx.kernalContext(), deploymentLdrId)) : ret.success(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicFullUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicFullUpdateRequest.java index 62fcf3966d916..2ad20466f7c16 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicFullUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicFullUpdateRequest.java @@ -29,6 +29,7 @@ import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.DeployableMessage; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheOperation; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; @@ -41,6 +42,8 @@ import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -51,7 +54,7 @@ /** * Lite DHT cache update request sent from near node to primary node. */ -public class GridNearAtomicFullUpdateRequest extends GridNearAtomicAbstractUpdateRequest { +public class GridNearAtomicFullUpdateRequest extends GridNearAtomicAbstractUpdateRequest implements MarshallableMessage, DeployableMessage { /** Keys to update. */ @Order(0) @GridToStringInclude @@ -62,7 +65,7 @@ public class GridNearAtomicFullUpdateRequest extends GridNearAtomicAbstractUpdat List vals; /** Entry processors. */ - private List> entryProcessors; + List> entryProcessors; /** Entry processors bytes. */ @Order(2) @@ -328,94 +331,69 @@ else if (conflictVers != null) } /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - if (expiryPlc != null && expiryPlcBytes == null) - expiryPlcBytes = CU.marshal(cctx, new IgniteExternalizableExpiryPolicy(expiryPlc)); - - prepareMarshalCacheObjects(keys, cctx); - - if (filter != null) { - boolean hasFilter = false; + @Override public int partition() { + assert !F.isEmpty(keys); - for (CacheEntryPredicate p : filter) { - if (p != null) { - hasFilter = true; + return keys.get(0).partition(); + } - p.prepareMarshal(cctx); - } - } + /** {@inheritDoc} */ + @Override public void cleanup(boolean clearKeys) { + vals = null; + entryProcessors = null; + entryProcessorsBytes = null; + invokeArgs = null; + invokeArgsBytes = null; - if (!hasFilter) - filter = null; - } + if (clearKeys) + keys = null; + } + /** {@inheritDoc} */ + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { + if (expiryPlc != null && expiryPlcBytes == null) + expiryPlcBytes = U.marshal(marsh, new IgniteExternalizableExpiryPolicy(expiryPlc)); + if (operation() == TRANSFORM) { - // force addition of deployment info for entry processors if P2P is enabled globally. - if (!addDepInfo && ctx.deploymentEnabled()) - addDepInfo = true; - if (entryProcessorsBytes == null) - entryProcessorsBytes = marshalCollection(entryProcessors, cctx); + entryProcessorsBytes = marshallCollection(entryProcessors, marsh); if (!F.isEmpty(invokeArgs) && invokeArgsBytes == null) - invokeArgsBytes = Arrays.asList(marshalInvokeArguments(invokeArgs, cctx)); + invokeArgsBytes = Arrays.asList(marshallInvokeArguments(invokeArgs, marsh)); } - else - prepareMarshalCacheObjects(vals, cctx); } /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (expiryPlcBytes != null && expiryPlc == null) - expiryPlc = U.unmarshal(ctx, expiryPlcBytes, U.resolveClassLoader(ldr, ctx.gridConfig())); - - finishUnmarshalCacheObjects(keys, cctx, ldr); - - if (filter != null) { - for (CacheEntryPredicate p : filter) { - if (p != null) - p.finishUnmarshal(cctx, ldr); - } - } + expiryPlc = U.unmarshal(marsh, expiryPlcBytes, clsLdr); if (operation() == TRANSFORM) { if (entryProcessors == null) - entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); + entryProcessors = unmarshalCollection(entryProcessorsBytes, marsh, clsLdr); if (invokeArgsBytes != null && invokeArgs == null) - invokeArgs = unmarshalInvokeArguments(invokeArgsBytes.toArray(new byte[invokeArgsBytes.size()][]), ctx, ldr); + invokeArgs = unmarshalInvokeArguments(invokeArgsBytes.toArray(new byte[invokeArgsBytes.size()][]), marsh, clsLdr); } - else - finishUnmarshalCacheObjects(vals, cctx, ldr); } /** {@inheritDoc} */ - @Override public int partition() { - assert !F.isEmpty(keys); + @Override public void deploy(GridCacheSharedContext ctx) throws IgniteCheckedException { + if (filter != null && filter.length == 0) + filter = null; - return keys.get(0).partition(); - } + if (operation() == TRANSFORM) { + GridCacheContext cctx = ctx.cacheContext(cacheId); - /** {@inheritDoc} */ - @Override public void cleanup(boolean clearKeys) { - vals = null; - entryProcessors = null; - entryProcessorsBytes = null; - invokeArgs = null; - invokeArgsBytes = null; + forceDeploymentInfo(ctx); - if (clearKeys) - keys = null; - } + if (entryProcessorsBytes == null) + deployCollection(entryProcessors, cctx); + if (!F.isEmpty(invokeArgs) && invokeArgsBytes == null) + deployInvokeArguments(invokeArgs, cctx); + } + } /** {@inheritDoc} */ @Override public String toString() { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFilterRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFilterRequest.java index 7b072491d4f89..d5bdab4971dce 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFilterRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFilterRequest.java @@ -19,14 +19,11 @@ import java.util.Arrays; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.CacheWriteSynchronizationMode; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheOperation; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.util.typedef.internal.S; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -91,43 +88,6 @@ public GridNearAtomicSingleUpdateFilterRequest() { return filter; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - if (filter != null) { - boolean hasFilter = false; - - for (CacheEntryPredicate p : filter) { - if (p != null) { - hasFilter = true; - - p.prepareMarshal(cctx); - } - } - - if (!hasFilter) - filter = null; - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (filter != null) { - GridCacheContext cctx = ctx.cacheContext(cacheId); - - for (CacheEntryPredicate p : filter) { - if (p != null) - p.finishUnmarshal(cctx, ldr); - } - } - } - - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridNearAtomicSingleUpdateFilterRequest.class, this, "filter", Arrays.toString(filter), diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java index cdbb251d049af..94b8db2443068 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateFuture.java @@ -253,11 +253,11 @@ else if (res.error() != null) if (op == TRANSFORM) { if (ret != null) { - assert ret.value() == null || ret.value() instanceof Map : ret.value(); + assert ret.value(cctx) == null || ret.value(cctx) instanceof Map : ret.value(cctx); - if (ret.value() != null) { + if (ret.value(cctx) != null) { if (opRes != null) - opRes.mergeEntryProcessResults(ret); + opRes.mergeEntryProcessResults(cctx, ret); else opRes = ret; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateInvokeRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateInvokeRequest.java index 2b2e44f5e7ea7..bf6ee8069f67d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateInvokeRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateInvokeRequest.java @@ -24,18 +24,20 @@ import javax.cache.processor.EntryProcessor; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.DeployableMessage; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheOperation; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.typedef.F; -import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,7 +46,8 @@ /** * */ -public class GridNearAtomicSingleUpdateInvokeRequest extends GridNearAtomicSingleUpdateRequest { +public class GridNearAtomicSingleUpdateInvokeRequest extends GridNearAtomicSingleUpdateRequest + implements MarshallableMessage, DeployableMessage { /** Optional arguments for entry processor. */ private @Nullable Object[] invokeArgs; @@ -53,7 +56,8 @@ public class GridNearAtomicSingleUpdateInvokeRequest extends GridNearAtomicSingl @Nullable List invokeArgsBytes; /** Entry processors. */ - private @Nullable EntryProcessor entryProc; + @Marshalled("entryProcBytes") + @Nullable EntryProcessor entryProc; /** Entry processors bytes. */ @Order(1) @@ -160,44 +164,38 @@ public GridNearAtomicSingleUpdateInvokeRequest() { } /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - // force addition of deployment info for entry processors if P2P is enabled globally. - if (!addDepInfo && ctx.deploymentEnabled()) - addDepInfo = true; - - if (entryProc != null && entryProcBytes == null) { - if (addDepInfo) - prepareObject(entryProc, cctx); + @Override public void cleanup(boolean clearKey) { + super.cleanup(clearKey); - entryProcBytes = CU.marshal(cctx, entryProc); - } + entryProc = null; + } + /** {@inheritDoc} */ + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { if (!F.isEmpty(invokeArgs) && invokeArgsBytes == null) - invokeArgsBytes = Arrays.asList(marshalInvokeArguments(invokeArgs, cctx)); + invokeArgsBytes = Arrays.asList(marshallInvokeArguments(invokeArgs, marsh)); } /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (entryProcBytes != null && entryProc == null) - entryProc = U.unmarshal(ctx, entryProcBytes, U.resolveClassLoader(ldr, ctx.gridConfig())); - + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (invokeArgsBytes != null && invokeArgs == null) - invokeArgs = unmarshalInvokeArguments(invokeArgsBytes.toArray(new byte[invokeArgsBytes.size()][]), ctx, ldr); + invokeArgs = unmarshalInvokeArguments(invokeArgsBytes.toArray(new byte[invokeArgsBytes.size()][]), marsh, clsLdr); } /** {@inheritDoc} */ - @Override public void cleanup(boolean clearKey) { - super.cleanup(clearKey); + @Override public void deploy(GridCacheSharedContext ctx) throws IgniteCheckedException { + GridCacheContext cctx = ctx.cacheContext(cacheId); - entryProc = null; - } + forceDeploymentInfo(ctx); + if (entryProc != null && entryProcBytes == null) { + if (addDepInfo) + deployObject(entryProc, cctx); + } + + if (!F.isEmpty(invokeArgs) && invokeArgsBytes == null) + deployInvokeArguments(invokeArgs, cctx); + } /** {@inheritDoc} */ @Override public String toString() { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java index 25b31b062c7c3..80b8d0b2f0e96 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicSingleUpdateRequest.java @@ -22,15 +22,12 @@ import java.util.UUID; import javax.cache.expiry.ExpiryPolicy; import javax.cache.processor.EntryProcessor; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.CacheWriteSynchronizationMode; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheOperation; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.GridCacheUtils; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; @@ -216,30 +213,6 @@ public GridNearAtomicSingleUpdateRequest() { return CU.EXPIRE_TIME_CALCULATE; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObject(key, cctx); - - if (val != null) - prepareMarshalCacheObject(val, cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - key.finishUnmarshal(cctx.cacheObjectContext(), ldr); - - if (val != null) - val.finishUnmarshal(cctx.cacheObjectContext(), ldr); - } - /** {@inheritDoc} */ @Override public void cleanup(boolean clearKey) { val = null; @@ -247,8 +220,7 @@ public GridNearAtomicSingleUpdateRequest() { if (clearKey) key = null; } - - + /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridNearAtomicSingleUpdateRequest.class, this, "parent", super.toString()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index a0714a324c968..94fdc0c8ec0e8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -417,11 +417,11 @@ else if (res.error() != null) if (op == TRANSFORM) { if (ret != null) { - assert ret.value() == null || ret.value() instanceof Map : ret.value(); + assert ret.value(cctx) == null || ret.value(cctx) instanceof Map : ret.value(cctx); - if (ret.value() != null) { + if (ret.value(cctx) != null) { if (opRes != null) - opRes.mergeEntryProcessResults(ret); + opRes.mergeEntryProcessResults(cctx, ret); else opRes = ret; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java index a1103fb308d55..066ba444f0fe6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java @@ -25,6 +25,7 @@ import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.DeployableMessage; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; @@ -39,7 +40,7 @@ /** * DHT atomic cache near update response. */ -public class GridNearAtomicUpdateResponse extends GridCacheIdMessage implements GridCacheDeployable { +public class GridNearAtomicUpdateResponse extends GridCacheIdMessage implements GridCacheDeployable, DeployableMessage { /** Cache message index. */ public static final int CACHE_MSG_IDX = nextIndexId(); @@ -337,39 +338,6 @@ synchronized void addFailedKeys(Collection keys, Throwable e) { errs.addFailedKeys(keys, e); } - /** {@inheritDoc} - * @param ctx*/ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - if (errs != null) - errs.prepareMarshal(this, cctx); - - if (nearUpdates != null) - prepareMarshalCacheObjects(nearUpdates.nearValues(), cctx); - - if (ret != null) - ret.prepareMarshal(cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - if (errs != null) - errs.finishUnmarshal(this, cctx, ldr); - - if (nearUpdates != null) - finishUnmarshalCacheObjects(nearUpdates.nearValues(), cctx, ldr); - - if (ret != null) - ret.finishUnmarshal(cctx, ldr); - } - /** * @return Data for near cache update. */ @@ -406,6 +374,14 @@ public void partition(int partId) { return ctx.atomicMessageLogger(); } + /** {@inheritDoc} */ + @Override public void deploy(GridCacheSharedContext ctx) throws IgniteCheckedException { + if (nearUpdates != null) { + GridCacheContext cctx = ctx.cacheContext(cacheId); + + deployCacheObjects(nearUpdates.nearValues(), cctx); + } + } /** {@inheritDoc} */ @Override public String toString() { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/UpdateErrors.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/UpdateErrors.java index 0e42f82082251..820b5d7b4d17a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/UpdateErrors.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/UpdateErrors.java @@ -23,8 +23,6 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.communication.ErrorMessage; -import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; @@ -115,17 +113,6 @@ void addFailedKeys(Collection keys, Throwable e) { errMsg.error().addSuppressed(e); } - /** */ - void prepareMarshal(GridCacheMessage msg, GridCacheContext cctx) throws IgniteCheckedException { - msg.prepareMarshalCacheObjects(failedKeys, cctx); - } - - /** */ - void finishUnmarshal(GridCacheMessage msg, GridCacheContext cctx, ClassLoader ldr) throws IgniteCheckedException { - msg.finishUnmarshalCacheObjects(failedKeys, cctx, ldr); - } - - /** {@inheritDoc} */ @Override public String toString() { return S.toString(UpdateErrors.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysRequest.java index 898ad4478f086..36e74d86c20be 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysRequest.java @@ -18,13 +18,10 @@ package org.apache.ignite.internal.processors.cache.distributed.dht.preloader; import java.util.Collection; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.F; @@ -113,24 +110,6 @@ public Collection keys() { return topVer; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(keys, cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(keys, cctx, ldr); - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return addDepInfo; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysResponse.java index cafcb5fa3e364..09afa95023c1b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysResponse.java @@ -23,11 +23,9 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.communication.ErrorMessage; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.F; @@ -131,42 +129,11 @@ public void addInfo(GridCacheEntryInfo info) { infos.add(info); } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - if (missedKeys != null) - prepareMarshalCacheObjects(missedKeys, cctx); - - if (infos != null) { - for (GridCacheEntryInfo info : infos) - info.marshal(cctx.cacheObjectContext()); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - if (missedKeys != null) - finishUnmarshalCacheObjects(missedKeys, cctx, ldr); - - if (infos != null) { - for (GridCacheEntryInfo info : infos) - info.unmarshal(cctx.cacheObjectContext(), ldr); - } - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return addDepInfo; } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridDhtForceKeysResponse.class, this, super.toString()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessage.java index a800ab4d1f7a8..8b85ce7913a6a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessage.java @@ -27,7 +27,6 @@ import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.communication.ErrorMessage; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.CacheGroupContext; import org.apache.ignite.internal.processors.cache.CacheObjectContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo; @@ -215,7 +214,7 @@ void addEntry0(int p, boolean historical, GridCacheEntryInfo info, GridCacheShar assert info.value() != null || historical : info; // Need to call this method to initialize info properly. - marshalInfo(info, ctx, cacheObjCtx); + deployInfo(info, ctx, cacheObjCtx); msgSize += info.marshalledSize(cacheObjCtx); @@ -230,21 +229,6 @@ void addEntry0(int p, boolean historical, GridCacheEntryInfo info, GridCacheShar infoCol.add(info); } - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - CacheGroupContext grp = ctx.cache().cacheGroup(grpId); - - if (grp == null) - return; - - for (List entries : getInfosSafe().values()) { - for (int i = 0; i < entries.size(); i++) - entries.get(i).unmarshal(grp.cacheObjectContext(), ldr); - } - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return addDepInfo; @@ -256,8 +240,7 @@ void addEntry0(int p, boolean historical, GridCacheEntryInfo info, GridCacheShar public int size() { return getInfosSafe().size(); } - - + /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridDhtPartitionSupplyMessage.class, this, diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java index e3c7b42dc7f6e..fb79d83c23ce4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java @@ -84,6 +84,7 @@ import org.apache.ignite.internal.processors.cache.ExchangeFailureMessage; import org.apache.ignite.internal.processors.cache.GridCacheAdapter; import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate; import org.apache.ignite.internal.processors.cache.GridCacheProcessor; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; @@ -3876,7 +3877,7 @@ else if (exchCtx.events().hasServerLeft()) else if (forceAffReassignment) msg.idealAffinityDiff(idealAffDiff); - msg.prepareMarshal(cctx); + GridCacheMessageDeployer.deploy(cctx.kernalContext().messageFactory(), msg, cctx); timeBag.finishGlobalStage("Full message preparing"); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java index f8fc363a829dd..b87878d849ad0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java @@ -28,7 +28,6 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.Compress; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.communication.ErrorMessage; import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; @@ -41,6 +40,7 @@ import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -92,17 +92,13 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa @Order(6) AffinityTopologyVersion topVer; - /** Exceptions. */ - @GridToStringInclude - private Map errs; - /** - * Used as a stub for serialization of {@link #errs}. - * All logic resides within getter and setter. + * Exceptions in wire form. The logical {@code Map} is exposed via + * {@link #getErrorsMap()} / {@link #setErrorsMap(Map)}. */ @Order(7) @Compress - @SuppressWarnings("unused") + @GridToStringInclude Map errMsgs; /** */ @@ -169,7 +165,7 @@ public GridDhtPartitionsFullMessage(@Nullable GridDhtPartitionExchangeId id, cp.partsToReload = partsToReload; cp.partsSizes = partsSizes; cp.topVer = topVer; - cp.errs = errs; + cp.errMsgs = errMsgs; cp.resTopVer = resTopVer; cp.joinedNodeAff = joinedNodeAff; cp.idealAffDiff = idealAffDiff; @@ -364,14 +360,17 @@ public Map> partitionSizes() { * @return Errors map. */ @Nullable Map getErrorsMap() { - return errs; + return errMsgs == null ? null : F.viewReadOnly(errMsgs, e -> e.error()); } /** * @param errs Errors map. */ void setErrorsMap(Map errs) { - this.errs = new HashMap<>(errs); + errMsgs = new HashMap<>(); + + for (Map.Entry e : errs.entrySet()) + errMsgs.put(e.getKey(), new ErrorMessage(e.getValue())); } /** @@ -389,11 +388,9 @@ public void rebalanced(boolean rebalanced) { } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { if (!F.isEmpty(parts) && locParts == null) locParts = copyPartitionsMap(parts); - - errMsgs = errs == null ? null : F.viewReadOnly(errs, ErrorMessage::new); } /** @@ -411,7 +408,7 @@ public void topologyVersion(AffinityTopologyVersion topVer) { } /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (locParts != null && parts == null) { parts = copyPartitionsMap(locParts); @@ -443,8 +440,6 @@ public void topologyVersion(AffinityTopologyVersion topVer) { if (parts == null) parts = new HashMap<>(); - - errs = errMsgs == null ? null : F.viewReadOnly(errMsgs, e -> e.error()); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java index a4a28d2eed3c1..2fe5493e19696 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java @@ -25,12 +25,13 @@ import org.apache.ignite.internal.Compress; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.communication.ErrorMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.jetbrains.annotations.Nullable; /** @@ -38,7 +39,7 @@ * * Sent in response to {@link GridDhtPartitionsSingleRequest} and during processing partitions exchange future. */ -public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMessage { +public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMessage implements MarshallableMessage { /** Local partitions. */ @Order(0) @Compress @@ -291,9 +292,12 @@ public void exchangeStartTime(long exchangeStartTime) { } /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { + // No-op. + } + /** {@inheritDoc} */ + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (dupPartsData != null) { assert parts != null; @@ -315,7 +319,6 @@ public void exchangeStartTime(long exchangeStartTime) { } } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridDhtPartitionsSingleMessage.class, this, super.toString()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/CacheVersionedValue.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/CacheVersionedValue.java index af5d90f84d2a2..5546df99c8806 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/CacheVersionedValue.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/CacheVersionedValue.java @@ -17,20 +17,18 @@ package org.apache.ignite.internal.processors.cache.distributed.near; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.CacheObjectContext; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.plugin.extensions.communication.CacheIdAware; import org.apache.ignite.plugin.extensions.communication.Message; /** * Cache object and version. */ -public class CacheVersionedValue implements Message { +public class CacheVersionedValue implements Message, CacheIdAware { /** Value. */ @Order(0) @GridToStringInclude @@ -40,19 +38,21 @@ public class CacheVersionedValue implements Message { @Order(1) @GridToStringInclude GridCacheVersion ver; + + /** */ + @Order(2) + int cacheId; /** */ public CacheVersionedValue() { // No-op. } - /** - * @param val Cache value. - * @param ver Cache version. - */ - public CacheVersionedValue(CacheObject val, GridCacheVersion ver) { + /** */ + public CacheVersionedValue(CacheObject val, GridCacheVersion ver, int cacheId) { this.val = val; this.ver = ver; + this.cacheId = cacheId; } /** @@ -69,34 +69,14 @@ public CacheObject value() { return val; } - /** - * This method is called before the whole message is sent - * and is responsible for pre-marshalling state. - * - * @param ctx Cache object context. - * @throws IgniteCheckedException If failed. - */ - public void prepareMarshal(CacheObjectContext ctx) throws IgniteCheckedException { - if (val != null) - val.prepareMarshal(ctx); - } - - /** - * This method is called after the whole message is received - * and is responsible for unmarshalling state. - * - * @param ctx Context. - * @param ldr Class loader. - * @throws IgniteCheckedException If failed. - */ - public void finishUnmarshal(GridCacheContext ctx, ClassLoader ldr) throws IgniteCheckedException { - if (val != null) - val.finishUnmarshal(ctx.cacheObjectContext(), ldr); - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(CacheVersionedValue.class, this); } + + /** {@inheritDoc} */ + @Override public int cacheId() { + return cacheId; + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java index a8df9c74253c6..75ef1509bc4af 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java @@ -628,8 +628,6 @@ private Map loadEntries( for (GridCacheEntryInfo info : infos) { try { - info.unmarshalValue(cctx, cctx.deploy().globalLoader()); - // Entries available locally in DHT should not be loaded into near cache for reading. if (!cctx.affinity().keyLocalNode(info.key(), cctx.affinity().affinityTopologyVersion())) { GridNearCacheEntry entry = savedEntries.get(info.key()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java index 74ad48394405d..972aa6f0ebe0b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java @@ -22,13 +22,10 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.processors.cache.version.GridCacheVersionable; @@ -43,8 +40,7 @@ /** * Get request. Responsible for obtaining entry from primary node. 'Near' means 'Initiating node' here, not 'Near Cache'. */ -public class GridNearGetRequest extends GridCacheIdMessage implements GridCacheDeployable, - GridCacheVersionable { +public class GridNearGetRequest extends GridCacheIdMessage implements GridCacheDeployable, GridCacheVersionable { /** */ private static final int READ_THROUGH_FLAG_MASK = 0x01; @@ -215,6 +211,18 @@ public int taskNameHash() { * @return Keys. */ public LinkedHashMap keyMap() { + if (keyMap == null && !F.isEmpty(keys)) { + keyMap = U.newLinkedHashMap(keys.size()); + + Iterator keysIt = keys.iterator(); + + for (int i = 0; i < keys.size(); i++) { + Boolean addRdr = readersFlags != null ? readersFlags.get(i) : Boolean.FALSE; + + keyMap.put(keysIt.next(), addRdr); + } + } + return keyMap; } @@ -280,56 +288,11 @@ public long accessTtl() { return txLbl; } - /** - * @param ctx Cache context. - * @throws IgniteCheckedException If failed. - */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - assert ctx != null; - assert !F.isEmpty(keys); - assert readersFlags == null || keys.size() == readersFlags.size(); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObjects(keys, cctx); - } - - /** - * @param ctx Context. - * @param ldr Loader. - * @throws IgniteCheckedException If failed. - */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - finishUnmarshalCacheObjects(keys, cctx, ldr); - - assert !F.isEmpty(keys); - assert readersFlags == null || keys.size() == readersFlags.size(); - - if (keyMap == null) { - keyMap = U.newLinkedHashMap(keys.size()); - - Iterator keysIt = keys.iterator(); - - for (int i = 0; i < keys.size(); i++) { - Boolean addRdr = readersFlags != null ? readersFlags.get(i) : Boolean.FALSE; - - keyMap.put(keysIt.next(), addRdr); - } - } - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return addDepInfo; } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridNearGetRequest.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java index 56f0aa1ca803d..c8a8c84b6b148 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java @@ -19,15 +19,12 @@ import java.util.Collection; import java.util.Collections; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.communication.ErrorMessage; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.processors.cache.version.GridCacheVersionable; import org.apache.ignite.internal.util.GridLeanSet; @@ -173,31 +170,6 @@ public void error(@Nullable Throwable err) { errMsg = new ErrorMessage(err); } - /** {@inheritDoc} - * @param ctx*/ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - if (entries != null) { - for (GridCacheEntryInfo info : entries) - info.marshal(cctx); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - GridCacheContext cctx = ctx.cacheContext(cacheId()); - - if (entries != null) { - for (GridCacheEntryInfo info : entries) - info.unmarshal(cctx, ldr); - } - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return addDepInfo; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetRequest.java index 07ca1355fc0f0..45bb7739bf4ae 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetRequest.java @@ -17,13 +17,10 @@ package org.apache.ignite.internal.processors.cache.distributed.near; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.util.typedef.internal.S; import org.jetbrains.annotations.NotNull; @@ -249,28 +246,6 @@ public boolean recovery() { return (flags & RECOVERY_FLAG_MASK) != 0; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - assert key != null; - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - prepareMarshalCacheObject(key, cctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - assert key != null; - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - key.finishUnmarshal(cctx.cacheObjectContext(), ldr); - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return addDepInfo; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetResponse.java index 73f72ec4c0247..fcccd4494aca2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetResponse.java @@ -22,9 +22,9 @@ import org.apache.ignite.internal.managers.communication.ErrorMessage; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.DeployableMessage; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; -import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.util.typedef.internal.S; @@ -34,7 +34,7 @@ /** * */ -public class GridNearSingleGetResponse extends GridCacheIdMessage implements GridCacheDeployable { +public class GridNearSingleGetResponse extends GridCacheIdMessage implements GridCacheDeployable, DeployableMessage { /** */ public static final int INVALID_PART_FLAG_MASK = 0x1; @@ -145,34 +145,11 @@ public long futureId() { } /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (res != null) { + @Override public void deploy(GridCacheSharedContext ctx) throws IgniteCheckedException { + if (res instanceof CacheObject) { GridCacheContext cctx = ctx.cacheContext(cacheId); - if (res instanceof CacheObject) - prepareMarshalCacheObject((CacheObject)res, cctx); - else if (res instanceof CacheVersionedValue) - ((CacheVersionedValue)res).prepareMarshal(cctx.cacheObjectContext()); - else if (res instanceof GridCacheEntryInfo) - ((GridCacheEntryInfo)res).marshal(cctx); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (res != null) { - GridCacheContext cctx = ctx.cacheContext(cacheId()); - - if (res instanceof CacheObject) - ((CacheObject)res).finishUnmarshal(cctx.cacheObjectContext(), ldr); - else if (res instanceof CacheVersionedValue) - ((CacheVersionedValue)res).finishUnmarshal(cctx, ldr); - else if (res instanceof GridCacheEntryInfo) - ((GridCacheEntryInfo)res).unmarshal(cctx, ldr); + deployCacheObject((CacheObject)res, cctx); } } @@ -181,7 +158,6 @@ else if (res instanceof GridCacheEntryInfo) return addDepInfo; } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridNearSingleGetResponse.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java index f0f4ddaaf26d1..ba60bd7ded420 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java @@ -1809,7 +1809,7 @@ private IgniteInternalFuture removeAllAsync0( true, keepBinary, U.deploymentClassLoader(cctx.kernalContext(), deploymentLdrId), - implicitRes.value(), + implicitRes.value(cacheCtx), implicitRes.success() ); } @@ -2672,7 +2672,7 @@ private IgniteInternalFuture optimisticPutFuture( try { txFut.get(); - Object res = implicitRes.value(); + Object res = implicitRes.value(cacheCtx); if (implicitRes.invokeResult()) { assert res == null || res instanceof Map : implicitRes; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java index 05b7f6ef918a1..a9ada7e55545a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java @@ -265,11 +265,6 @@ private Collection cloneEntries(Collection c) { return cp; } - /** {@inheritDoc} */ - @Override protected boolean transferExpiryPolicy() { - return true; - } - /** * Sets flag mask. * diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java index 646335209b86e..b352bb7538a74 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java @@ -20,22 +20,18 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.MarshalledMap; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheReturn; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxPrepareResponse; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteUuid; import org.jetbrains.annotations.Nullable; @@ -66,7 +62,8 @@ public class GridNearTxPrepareResponse extends GridDistributedTxPrepareResponse /** Map of owned values to set on near node. */ @GridToStringInclude - private Map ownedVals; + @MarshalledMap(keys = "ownedValKeys", values = "ownedValVals") + Map ownedVals; /** OwnedVals' keys for marshalling. */ @Order(5) @@ -196,7 +193,7 @@ public void addOwnedValue(IgniteTxKey key, GridCacheVersion ver, CacheObject val if (ownedVals == null) ownedVals = new HashMap<>(); - CacheVersionedValue oVal = new CacheVersionedValue(val, ver); + CacheVersionedValue oVal = new CacheVersionedValue(val, ver, key.cacheId()); ownedVals.put(key, oVal); } @@ -235,97 +232,6 @@ public boolean hasOwnedValue(IgniteTxKey key) { return F.mapContainsKey(ownedVals, key); } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - // There are separate collections for keys and values of the 'ownedVals' map, because IgniteTxKey - // can not be inserted directly in a map as a key during invocation of MessageReader#read. - // The IgniteTxKey's hash code calculation will fail due to delegation of calculation - // to KeyCacheObjectImpl#hashCode, which in turn fails with assertion error if KeyCacheObjectImpl#val - // has not initialized yet in KeyCacheObjectImpl#finishUnmarshal. - if (ownedVals != null && ownedValKeys == null) { - ownedValKeys = ownedVals.keySet(); - - ownedValVals = ownedVals.values(); - - for (Map.Entry entry : ownedVals.entrySet()) { - GridCacheContext cacheCtx = ctx.cacheContext(entry.getKey().cacheId()); - - entry.getKey().prepareMarshal(cacheCtx); - - entry.getValue().prepareMarshal(cacheCtx.cacheObjectContext()); - } - } - - if (retVal != null && retVal.cacheId() != 0) { - GridCacheContext cctx = ctx.cacheContext(retVal.cacheId()); - - assert cctx != null : retVal.cacheId(); - - retVal.prepareMarshal(cctx); - } - - if (filterFailedKeys != null) { - for (IgniteTxKey key : filterFailedKeys) { - GridCacheContext cctx = ctx.cacheContext(key.cacheId()); - - key.prepareMarshal(cctx); - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - // There are separate collections for keys and values of the 'ownedVals' map, because IgniteTxKey - // can not be inserted directly in a map as a key during invocation of MessageReader#read. - // The IgniteTxKey's hash code calculation will fail due to delegation of calculation - // to KeyCacheObjectImpl#hashCode, which in turn fails with assertion error if KeyCacheObjectImpl#val - // has not initialized yet in KeyCacheObjectImpl#finishUnmarshal. - if (ownedValKeys != null && ownedVals == null) { - ownedVals = U.newHashMap(ownedValKeys.size()); - - assert ownedValKeys.size() == ownedValVals.size(); - - Iterator keyIter = ownedValKeys.iterator(); - - Iterator valIter = ownedValVals.iterator(); - - while (keyIter.hasNext()) { - IgniteTxKey key = keyIter.next(); - - GridCacheContext cctx = ctx.cacheContext(key.cacheId()); - - CacheVersionedValue val = valIter.next(); - - key.finishUnmarshal(cctx, ldr); - - val.finishUnmarshal(cctx, ldr); - - ownedVals.put(key, val); - } - } - - if (retVal != null && retVal.cacheId() != 0) { - GridCacheContext cctx = ctx.cacheContext(retVal.cacheId()); - - assert cctx != null : retVal.cacheId(); - - retVal.finishUnmarshal(cctx, ldr); - } - - if (filterFailedKeys != null) { - for (IgniteTxKey key : filterFailedKeys) { - GridCacheContext cctx = ctx.cacheContext(key.cacheId()); - - key.finishUnmarshal(cctx, ldr); - } - } - } - - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridNearTxPrepareResponse.class, this, "super", super.toString()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java index 936033d8b3838..6023dbd144c27 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java @@ -25,6 +25,7 @@ import java.util.UUID; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheInvalidStateException; import org.apache.ignite.internal.processors.cache.CacheObject; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; @@ -126,9 +127,14 @@ public GridNearTxRemote( if (writeEntries != null) { for (IgniteTxEntry entry : writeEntries) { - entry.unmarshal(ctx, true, ldr); + try { + entry.initializeContext(ctx, topVer, true); - addEntry(entry); + addEntry(entry); + } + catch (CacheInvalidStateException e) { + // Cache was destroyed. + } } } @@ -203,9 +209,14 @@ public Collection evicted() { */ public void addEntries(ClassLoader ldr, Iterable entries) throws IgniteCheckedException { for (IgniteTxEntry entry : entries) { - entry.unmarshal(cctx, true, ldr); + try { + entry.initializeContext(cctx, topVer, true); - addEntry(entry); + addEntry(entry); + } + catch (CacheInvalidStateException e) { + // Cache was destroyed. + } } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotAwareMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotAwareMessage.java index 5a0824c9a5d41..cfaa9eb031402 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotAwareMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotAwareMessage.java @@ -18,10 +18,8 @@ package org.apache.ignite.internal.processors.cache.persistence.snapshot; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.GridCacheMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.jetbrains.annotations.Nullable; /** @@ -81,17 +79,6 @@ public long snapshotTopologyVersion() { return topVer; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - payload.prepareMarshal(ctx); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - payload.finishUnmarshal(ctx, ldr); - } - - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return false; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotVerifyResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotVerifyResult.java index 641e123ffff69..b6614c8535c38 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotVerifyResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotVerifyResult.java @@ -17,6 +17,7 @@ package org.apache.ignite.internal.processors.cache.persistence.snapshot; +import java.util.ArrayList; import java.util.Collection; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.communication.ErrorMessage; @@ -24,7 +25,6 @@ import org.apache.ignite.internal.processors.cache.verify.PartitionHashRecord; import org.apache.ignite.internal.processors.cache.verify.TransactionsHashRecord; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; @@ -64,7 +64,14 @@ public IncrementalSnapshotVerifyResult() { this.txHashRes = txHashRes; this.partHashRes = partHashRes; this.partiallyCommittedTxs = partiallyCommittedTxs; - this.exceptions = exceptions == null ? null : F.viewReadOnly(exceptions, ErrorMessage::new); + + if (exceptions != null) { + this.exceptions = new ArrayList<>(); + + for (Throwable th : exceptions) { + this.exceptions.add(new ErrorMessage(th)); + } + } } /** */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryRequest.java index 84813c40420c9..3f21d760df663 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryRequest.java @@ -19,9 +19,10 @@ import java.util.Collection; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.processors.cache.DeployableMessage; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; @@ -29,7 +30,6 @@ import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.F; -import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiPredicate; @@ -45,7 +45,7 @@ /** * Query request. */ -public class GridCacheQueryRequest extends GridCacheIdMessage implements GridCacheDeployable { +public class GridCacheQueryRequest extends GridCacheIdMessage implements GridCacheDeployable, DeployableMessage { /** */ private static final int FLAG_DATA_PAGE_SCAN_DFLT = 0b00; @@ -76,7 +76,8 @@ public class GridCacheQueryRequest extends GridCacheIdMessage implements GridCac String clause; /** */ - private IndexQueryDesc idxQryDesc; + @Marshalled("idxQryDescBytes") + IndexQueryDesc idxQryDesc; /** */ @Order(4) @@ -91,28 +92,32 @@ public class GridCacheQueryRequest extends GridCacheIdMessage implements GridCac String clsName; /** */ - private IgniteBiPredicate keyValFilter; + @Marshalled("keyValFilterBytes") + IgniteBiPredicate keyValFilter; /** */ @Order(7) byte[] keyValFilterBytes; /** */ - private IgniteReducer rdc; + @Marshalled("rdcBytes") + IgniteReducer rdc; /** */ @Order(8) byte[] rdcBytes; /** */ - private IgniteClosure trans; + @Marshalled("transBytes") + IgniteClosure trans; /** */ @Order(9) byte[] transBytes; /** */ - private Object[] args; + @Marshalled("argsBytes") + Object[] args; /** */ @Order(10) @@ -406,86 +411,6 @@ private static byte setDataPageScanEnabled(int flags, Boolean enabled) { return topVer != null ? topVer : AffinityTopologyVersion.NONE; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - if (keyValFilter != null && keyValFilterBytes == null) { - if (addDepInfo) - prepareObject(keyValFilter, cctx); - - keyValFilterBytes = CU.marshal(cctx, keyValFilter); - } - - if (rdc != null && rdcBytes == null) { - if (addDepInfo) - prepareObject(rdc, cctx); - - rdcBytes = CU.marshal(cctx, rdc); - } - - if (trans != null && transBytes == null) { - if (addDepInfo) - prepareObject(trans, cctx); - - transBytes = CU.marshal(cctx, trans); - } - - if (!F.isEmpty(args) && argsBytes == null) { - if (addDepInfo) { - for (Object arg : args) - prepareObject(arg, cctx); - } - - argsBytes = CU.marshal(cctx, args); - } - - if (idxQryDesc != null && idxQryDescBytes == null) { - if (addDepInfo) - prepareObject(idxQryDesc, cctx); - - idxQryDescBytes = CU.marshal(cctx, idxQryDesc); - } - - if (!F.isEmpty(skipKeys)) { - for (KeyCacheObject k : skipKeys) - k.prepareMarshal(cctx.cacheObjectContext()); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - Marshaller mrsh = ctx.marshaller(); - - ClassLoader clsLdr = U.resolveClassLoader(ldr, ctx.gridConfig()); - - if (keyValFilterBytes != null && keyValFilter == null) - keyValFilter = U.unmarshal(mrsh, keyValFilterBytes, clsLdr); - - if (rdcBytes != null && rdc == null) - rdc = U.unmarshal(mrsh, rdcBytes, ldr); - - if (transBytes != null && trans == null) - trans = U.unmarshal(mrsh, transBytes, clsLdr); - - if (argsBytes != null && args == null) - args = U.unmarshal(mrsh, argsBytes, clsLdr); - - if (idxQryDescBytes != null && idxQryDesc == null) - idxQryDesc = U.unmarshal(mrsh, idxQryDescBytes, clsLdr); - - if (!F.isEmpty(skipKeys)) { - CacheObjectContext objCtx = ctx.cacheObjectContext(cacheId); - - for (KeyCacheObject k : skipKeys) - k.finishUnmarshal(objCtx, ldr); - } - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return addDepInfo; @@ -659,6 +584,37 @@ public Collection skipKeys() { return part; } + /** {@inheritDoc} */ + @Override public void deploy(GridCacheSharedContext ctx) throws IgniteCheckedException { + GridCacheContext cctx = ctx.cacheContext(cacheId); + + if (keyValFilter != null && keyValFilterBytes == null) { + if (addDepInfo) + deployObject(keyValFilter, cctx); + } + + if (rdc != null && rdcBytes == null) { + if (addDepInfo) + deployObject(rdc, cctx); + } + + if (trans != null && transBytes == null) { + if (addDepInfo) + deployObject(trans, cctx); + } + + if (!F.isEmpty(args) && argsBytes == null) { + if (addDepInfo) { + for (Object arg : args) + deployObject(arg, cctx); + } + } + + if (idxQryDesc != null && idxQryDescBytes == null) { + if (addDepInfo) + deployObject(idxQryDesc, cctx); + } + } /** {@inheritDoc} */ @Override public String toString() { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryResponse.java index 6b295f2561182..03b517e476931 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryResponse.java @@ -17,30 +17,26 @@ package org.apache.ignite.internal.processors.cache.query; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.Map; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.MarshalledObjects; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.cache.query.index.IndexQueryResultMeta; import org.apache.ignite.internal.managers.communication.ErrorMessage; -import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.processors.cache.DeployableMessage; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; -import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; import org.jetbrains.annotations.Nullable; /** * Page of cache query response. */ -public class GridCacheQueryResponse extends GridCacheIdMessage implements GridCacheDeployable { +public class GridCacheQueryResponse extends GridCacheIdMessage implements GridCacheDeployable, DeployableMessage { /** */ @Order(0) boolean finished; @@ -66,7 +62,8 @@ public class GridCacheQueryResponse extends GridCacheIdMessage implements GridCa Collection dataBytes; /** */ - private Collection data; + @MarshalledObjects("dataBytes") + Collection data; /** * Empty constructor. @@ -103,79 +100,6 @@ public GridCacheQueryResponse(int cacheId, long reqId, Throwable err, boolean ad finished = true; } - /** {@inheritDoc} - * @param ctx*/ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - GridCacheContext cctx = ctx.cacheContext(cacheId); - - if (dataBytes == null && data != null) - dataBytes = marshalCollection(data, cctx); - - if (addDepInfo && !F.isEmpty(data)) { - for (Object o : data) { - if (o instanceof Map.Entry) { - Map.Entry e = (Map.Entry)o; - - prepareObject(e.getKey(), cctx); - prepareObject(e.getValue(), cctx); - } - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - if (data == null) - data = unmarshalCollection0(dataBytes, ctx, ldr); - } - - /** - * @param byteCol Collection to unmarshal. - * @param ctx Context. - * @param ldr Loader. - * @return Unmarshalled collection. - * @throws IgniteCheckedException If failed. - */ - @Nullable protected List unmarshalCollection0(@Nullable Collection byteCol, - GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - assert ldr != null; - assert ctx != null; - - if (byteCol == null) - return null; - - List col = new ArrayList<>(byteCol.size()); - - Marshaller marsh = ctx.marshaller(); - - ClassLoader ldr0 = U.resolveClassLoader(ldr, ctx.gridConfig()); - - CacheObjectContext cacheObjCtx = null; - - for (byte[] bytes : byteCol) { - Object obj = bytes == null ? null : marsh.unmarshal(bytes, ldr0); - - if (obj instanceof Map.Entry) { - Object key = ((Map.Entry)obj).getKey(); - - if (key instanceof KeyCacheObject) { - if (cacheObjCtx == null) - cacheObjCtx = ctx.cacheContext(cacheId).cacheObjectContext(); - - ((KeyCacheObject)key).finishUnmarshal(cacheObjCtx, ldr0); - } - } - - col.add((T)obj); - } - - return col; - } - /** {@inheritDoc} */ @Override public boolean addDeploymentInfo() { return addDepInfo; @@ -233,6 +157,24 @@ public boolean fields() { return fields; } + /** {@inheritDoc} */ + @Override public void deploy(GridCacheSharedContext ctx) throws IgniteCheckedException { + GridCacheContext cctx = ctx.cacheContext(cacheId); + + if (dataBytes == null && data != null) + deployCollection(data, cctx); + + if (addDepInfo && !F.isEmpty(data)) { + for (Object o : data) { + if (o instanceof Map.Entry) { + Map.Entry e = (Map.Entry)o; + + deployObject(e.getKey(), cctx); + deployObject(e.getValue(), cctx); + } + } + } + } /** {@inheritDoc} */ @Override public String toString() { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEntry.java index 130dcec622821..ffe67490e0282 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEntry.java @@ -18,25 +18,23 @@ package org.apache.ignite.internal.processors.cache.query.continuous; import javax.cache.event.EventType; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheDeployable; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.CacheIdAware; +import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; /** * Continuous query entry. */ -public class CacheContinuousQueryEntry implements GridCacheDeployable, MarshallableMessage { +public class CacheContinuousQueryEntry implements GridCacheDeployable, Message, CacheIdAware { /** */ private static final byte BACKUP_ENTRY = 0b0001; @@ -56,27 +54,18 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Marshalla /** Key. */ @GridToStringInclude - KeyCacheObject key; - - /** */ @Order(2) - byte[] keyBytes; + KeyCacheObject key; /** New value. */ @GridToStringInclude - CacheObject newVal; - - /** */ @Order(3) - byte[] newValBytes; + CacheObject newVal; /** Old value. */ @GridToStringInclude - CacheObject oldVal; - - /** */ @Order(4) - byte[] oldValBytes; + CacheObject oldVal; /** Cache name. */ @Order(5) @@ -194,10 +183,8 @@ public byte flags() { return topVer; } - /** - * @return Cache ID. - */ - int cacheId() { + /** {@inheritDoc} */ + @Override public int cacheId() { return cacheId; } @@ -235,6 +222,9 @@ void markBackup() { void markFiltered() { flags |= FILTERED_ENTRY; depInfo = null; + key = null; + newVal = null; + oldVal = null; } /** @@ -295,39 +285,6 @@ boolean isKeepBinary() { return (flags & KEEP_BINARY) != 0; } - /** - * @param cctx Cache context. - * @throws IgniteCheckedException In case of error. - */ - void prepareMarshal(GridCacheContext cctx) throws IgniteCheckedException { - if (key != null) - key.prepareMarshal(cctx.cacheObjectContext()); - - if (newVal != null) - newVal.prepareMarshal(cctx.cacheObjectContext()); - - if (oldVal != null) - oldVal.prepareMarshal(cctx.cacheObjectContext()); - } - - /** - * @param cctx Cache context. - * @param ldr Class loader. - * @throws IgniteCheckedException In case of error. - */ - void unmarshal(GridCacheContext cctx, @Nullable ClassLoader ldr) throws IgniteCheckedException { - if (!isFiltered()) { - if (key != null) - key.finishUnmarshal(cctx.cacheObjectContext(), ldr); - - if (newVal != null) - newVal.finishUnmarshal(cctx.cacheObjectContext(), ldr); - - if (oldVal != null) - oldVal.finishUnmarshal(cctx.cacheObjectContext(), ldr); - } - } - /** * @return Key. */ @@ -350,7 +307,7 @@ CacheObject oldValue() { } /** {@inheritDoc} */ - @Override public void prepare(GridDeploymentInfo depInfo) { + @Override public void deploy(GridDeploymentInfo depInfo) { this.depInfo = depInfo; } @@ -358,36 +315,9 @@ CacheObject oldValue() { @Override public GridDeploymentInfo deployInfo() { return depInfo; } - - + /** {@inheritDoc} */ @Override public String toString() { return S.toString(CacheContinuousQueryEntry.class, this); } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (!isFiltered()) { - if (key != null) - keyBytes = marsh.marshal(key); - - if (newVal != null) - newValBytes = marsh.marshal(newVal); - - if (oldVal != null) - oldValBytes = marsh.marshal(oldVal); - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - if (keyBytes != null) - key = marsh.unmarshal(keyBytes, clsLdr); - - if (newValBytes != null) - newVal = marsh.unmarshal(newValBytes, clsLdr); - - if (oldValBytes != null) - oldVal = marsh.unmarshal(oldValBytes, clsLdr); - } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java index eca4f12544b83..d73e1ea05b3c9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java @@ -82,6 +82,7 @@ import org.apache.ignite.lang.IgniteAsyncCallback; import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.lang.IgniteClosure; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -932,13 +933,8 @@ protected CacheEntryEventFilter getEventFilter0() { */ private void prepareEntry(GridCacheContext cctx, UUID nodeId, CacheContinuousQueryEntry entry) throws IgniteCheckedException { - if (cctx.kernalContext().config().isPeerClassLoadingEnabled() && cctx.discovery().node(nodeId) != null) { - entry.prepareMarshal(cctx); - + if (cctx.kernalContext().config().isPeerClassLoadingEnabled() && cctx.discovery().node(nodeId) != null) cctx.deploy().prepare(entry); - } - else - entry.prepareMarshal(cctx); } /** @@ -1076,7 +1072,8 @@ private void notifyCallback0(UUID nodeId, } } - e.unmarshal(cctx, ldr); + MessageMarshaller.unmarshal( + cctx.kernalContext().messageFactory(), e, cctx.kernalContext(), null, cctx.deploy().globalLoader()); Collection> evts = handleEvent(ctx, e); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java index 1680b9619a2ef..b711e97cccc41 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java @@ -418,11 +418,11 @@ public void onEntryUpdated( oldVal = (CacheObject)cctx.unwrapTemporary(oldVal); if (oldVal != null) - oldVal.finishUnmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader()); + oldVal.unmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader()); } if (newVal != null) - newVal.finishUnmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader()); + newVal.unmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader()); initialized = true; } @@ -484,7 +484,7 @@ public void onEntryExpired(GridCacheEntryEx e, KeyCacheObject key, CacheObject o oldVal = (CacheObject)cctx.unwrapTemporary(oldVal); if (oldVal != null) - oldVal.finishUnmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader()); + oldVal.unmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader()); initialized = true; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java index 3139e9d8db007..0dc1cf07781b1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java @@ -25,13 +25,13 @@ import javax.cache.processor.EntryProcessor; import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.CacheEntryPredicate; import org.apache.ignite.internal.processors.cache.CacheInvalidStateException; import org.apache.ignite.internal.processors.cache.CacheInvokeEntry; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.CacheObjectValueContext; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; @@ -47,7 +47,9 @@ import org.apache.ignite.internal.util.typedef.T2; import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.CacheIdAware; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.apache.ignite.thread.IgniteThread; import org.jetbrains.annotations.Nullable; @@ -59,7 +61,7 @@ * {@link #equals(Object)} method, as transaction entries should use referential * equality. */ -public class IgniteTxEntry implements GridPeerDeployAware, Message { +public class IgniteTxEntry implements GridPeerDeployAware, MarshallableMessage, CacheIdAware { /** */ private static final long serialVersionUID = 0L; @@ -133,7 +135,8 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message { /** Transform. */ @GridToStringInclude - private Collection, Object[]>> entryProcessorsCol; + @Marshalled("transformClosBytes") + Collection, Object[]>> entryProcessorsCol; /** Transient field for calculated entry processor value. */ private T2 entryProcessorCalcVal; @@ -195,9 +198,6 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message { /** Expiry policy. */ private ExpiryPolicy expiryPlc; - /** Expiry policy transfer flag. */ - private boolean transferExpiryPlc; - /** Expiry policy bytes. */ @Order(10) byte[] expiryPlcBytes; @@ -415,7 +415,6 @@ public IgniteTxEntry copy() { cp.nodeId = nodeId; cp.locMapped = locMapped; cp.expiryPlc = expiryPlc; - cp.transferExpiryPlc = transferExpiryPlc; cp.expiryPlcBytes = expiryPlcBytes; cp.flags = flags; cp.partUpdateCntr = partUpdateCntr; @@ -460,7 +459,6 @@ public void restoreFrom(IgniteTxEntry snapshot) { nodeId = snapshot.nodeId; locMapped = snapshot.locMapped; expiryPlc = snapshot.expiryPlc; - transferExpiryPlc = snapshot.transferExpiryPlc; expiryPlcBytes = snapshot.expiryPlcBytes; flags = snapshot.flags; partUpdateCntr = snapshot.partUpdateCntr; @@ -594,7 +592,7 @@ public KeyCacheObject key() { /** * @return Cache ID. */ - public int cacheId() { + @Override public int cacheId() { return cacheId; } @@ -1041,52 +1039,35 @@ public void filtersSet(boolean filtersSet) { this.filtersSet = filtersSet; } - /** - * @param ctx Context. - * @param transferExpiry {@code True} if expire policy should be marshalled. - * @throws IgniteCheckedException If failed. - */ - public void marshal(GridCacheSharedContext ctx, boolean transferExpiry) throws IgniteCheckedException { - if (filters != null) { - for (CacheEntryPredicate p : filters) { - if (p != null) - p.prepareMarshal(this.ctx); - } - } - - // Do not serialize filters if they are null. - if (transformClosBytes == null && entryProcessorsCol != null) - transformClosBytes = CU.marshal(this.ctx, entryProcessorsCol); - - if (transferExpiry) - transferExpiryPlc = expiryPlc != null && expiryPlc != this.ctx.expiry(); - - key.prepareMarshal(context().cacheObjectContext()); - - val.marshal(context()); + /** {@inheritDoc} */ + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { + boolean transfer = expiryPlc != null && expiryPlc != ctx.expiry(); - if (transferExpiryPlc) { + if (transfer) { if (expiryPlcBytes == null) - expiryPlcBytes = CU.marshal(this.ctx, new IgniteExternalizableExpiryPolicy(expiryPlc)); + expiryPlcBytes = U.marshal(marsh, new IgniteExternalizableExpiryPolicy(expiryPlc)); } else expiryPlcBytes = null; + } - if (oldVal != null) - oldVal.marshal(context()); + /** {@inheritDoc} */ + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { + if (filters == null) + filters = CU.empty0(); + + if (expiryPlcBytes != null && expiryPlc == null) + expiryPlc = U.unmarshal(marsh, expiryPlcBytes, clsLdr); } /** - * Prepares this entry to unmarshall. In particular, this method initialize a cache context. - * * @param ctx Cache context. * @param topVer Topology version that is used to validate a cache context. * If this parameter is {@code null} then validation will be skipped. * @param near Near flag. * @throws IgniteCheckedException If un-marshalling failed. */ - public void prepareUnmarshal( - GridCacheSharedContext ctx, + public void initializeContext(GridCacheSharedContext ctx, AffinityTopologyVersion topVer, boolean near ) throws IgniteCheckedException { @@ -1106,53 +1087,6 @@ else if (!cacheCtx.isNear() && near) } } - /** - * Unmarshalls entry. - * - * @param ctx Cache context. - * @param near Near flag. - * @param clsLdr Class loader. - * @throws IgniteCheckedException If un-marshalling failed. - */ - public void unmarshal( - GridCacheSharedContext ctx, - boolean near, - ClassLoader clsLdr - ) throws IgniteCheckedException { - - if (this.ctx == null) - prepareUnmarshal(ctx, null, near); - - CacheObjectValueContext coctx = this.ctx.cacheObjectContext(); - - if (coctx == null) - throw new CacheInvalidStateException( - "Failed to perform cache operation (cache is stopped), cacheId=" + cacheId); - - // Unmarshal transform closure anyway if it exists. - if (transformClosBytes != null && entryProcessorsCol == null) - entryProcessorsCol = U.unmarshal(ctx, transformClosBytes, U.resolveClassLoader(clsLdr, ctx.gridConfig())); - - if (filters == null) - filters = CU.empty0(); - else { - for (CacheEntryPredicate p : filters) { - if (p != null) - p.finishUnmarshal(this.ctx, clsLdr); - } - } - - key.finishUnmarshal(coctx, clsLdr); - - val.unmarshal(coctx, clsLdr); - - if (expiryPlcBytes != null && expiryPlc == null) - expiryPlc = U.unmarshal(ctx, expiryPlcBytes, U.resolveClassLoader(clsLdr, ctx.gridConfig())); - - if (hasOldValue()) - oldVal.unmarshal(coctx, clsLdr); - } - /** * @param expiryPlc Expiry policy. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java index 40dae253a43f6..4e365428da014 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.UUID; @@ -374,14 +375,15 @@ public IgniteInternalFuture prepareColocatedTx( * @return First entry. * @throws IgniteCheckedException If failed. */ - private IgniteTxEntry unmarshal(@Nullable Collection entries) throws IgniteCheckedException { + private IgniteTxEntry initialize(@Nullable Collection entries, AffinityTopologyVersion topVer) + throws IgniteCheckedException { if (entries == null) return null; IgniteTxEntry firstEntry = null; for (IgniteTxEntry e : entries) { - e.unmarshal(ctx, false, ctx.deploy().globalLoader()); + e.initializeContext(ctx, topVer, false); if (firstEntry == null) firstEntry = e; @@ -430,12 +432,21 @@ public IgniteInternalFuture prepareNearTxLocal( IgniteTxEntry firstEntry; try { - IgniteTxEntry firstWrite = unmarshal(req.writes()); - IgniteTxEntry firstRead = unmarshal(req.reads()); + IgniteTxEntry firstWrite = initialize(req.writes(), req.topologyVersion()); + IgniteTxEntry firstRead = initialize(req.reads(), req.topologyVersion()); firstEntry = firstWrite != null ? firstWrite : firstRead; } catch (IgniteCheckedException e) { + try { + req.onClassError(e); + + ctx.io().processFailedMessage(nearNode.id(), req, null, req.policy()); + } + catch (IgniteCheckedException ex) { + throw new IgniteException(ex); + } + return new GridFinishedFuture<>(e); } @@ -1215,7 +1226,26 @@ private void processDhtTxPrepareRequest(final UUID nodeId, final GridDhtTxPrepar if (nearTx != null) res.nearEvicted(nearTx.evicted()); - List writesCacheMissed = req.nearWritesCacheMissed(); + List writesCacheMissed = new ArrayList<>(); + + Collection writes = req.nearWrites(); + + for (Iterator it = writes.iterator(); it.hasNext();) { + IgniteTxEntry e = it.next(); + + GridCacheContext cacheCtx = ctx.cacheContext(e.cacheId()); + + if (cacheCtx == null) { + it.remove(); + + writesCacheMissed.add(e.txKey()); + } + else { + e.context(cacheCtx); + + e.initializeContext(ctx, req.topologyVersion(), true); + } + } if (writesCacheMissed != null) { Collection evicted0 = res.nearEvicted(); @@ -1759,6 +1789,8 @@ private void sendReply(UUID nodeId, GridDhtTxFinishRequest req, boolean committe int idx = 0; for (IgniteTxEntry entry : req.writes()) { + entry.initializeContext(ctx, req.topologyVersion(), false); + GridCacheContext cacheCtx = entry.context(); int part = cacheCtx.affinity().partition(entry.key()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxKey.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxKey.java index b50bc340c3ba1..b428069ae4875 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxKey.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxKey.java @@ -17,19 +17,18 @@ package org.apache.ignite.internal.processors.cache.transactions; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.plugin.extensions.communication.CacheIdAware; import org.apache.ignite.plugin.extensions.communication.Message; /** * Cache transaction key. This wrapper is needed because same keys may be enlisted in the same transaction * for multiple caches. */ -public class IgniteTxKey implements Message { +public class IgniteTxKey implements Message, CacheIdAware { /** Key. */ @Order(0) @GridToStringInclude(sensitive = true) @@ -65,29 +64,10 @@ public KeyCacheObject key() { /** * @return Cache ID. */ - public int cacheId() { + @Override public int cacheId() { return cacheId; } - /** - * @param ctx Context. - * @throws IgniteCheckedException If failed. - */ - public void prepareMarshal(GridCacheContext ctx) throws IgniteCheckedException { - key.prepareMarshal(ctx.cacheObjectContext()); - } - - /** - * @param ctx Context. - * @param ldr Class loader. - * @throws IgniteCheckedException If failed. - */ - public void finishUnmarshal(GridCacheContext ctx, ClassLoader ldr) throws IgniteCheckedException { - assert key != null; - - key.finishUnmarshal(ctx.cacheObjectContext(), ldr); - } - /** {@inheritDoc} */ @Override public boolean equals(Object o) { if (this == o) @@ -110,7 +90,6 @@ public void finishUnmarshal(GridCacheContext ctx, ClassLoader ldr) throws Ignite return res; } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(IgniteTxKey.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java index bbc6e282fd5f0..67e72fd1fb162 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java @@ -326,7 +326,7 @@ public void implicitSingleResult(GridCacheReturn ret) { assert ret != null; if (ret.invokeResult()) - implicitRes.mergeEntryProcessResults(ret); + implicitRes.mergeEntryProcessResults(cctx.cacheContext(ret.cacheId()), ret); else implicitRes = ret; } @@ -1229,7 +1229,7 @@ protected final void postLockWrite( } else { // Revert operation to previous. (if no - NOOP, so entry will be unlocked). - txEntry.setAndMarkValid(txEntry.previousOperation(), cacheCtx.toCacheObject(ret.value())); + txEntry.setAndMarkValid(txEntry.previousOperation(), cacheCtx.toCacheObject(ret.value(cacheCtx))); txEntry.filters(CU.empty0()); txEntry.filtersSet(false); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java index e4a56ac880eee..4047b69ad39ac 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java @@ -67,6 +67,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; import org.apache.ignite.internal.processors.cache.GridCacheMapEntry; import org.apache.ignite.internal.processors.cache.GridCacheMessage; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate; import org.apache.ignite.internal.processors.cache.GridCacheReturnCompletableWrapper; import org.apache.ignite.internal.processors.cache.GridCacheSharedManagerAdapter; @@ -116,6 +117,7 @@ import org.apache.ignite.lang.IgniteFuture; import org.apache.ignite.lang.IgniteOutClosure; import org.apache.ignite.lang.IgniteReducer; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.spi.systemview.view.TransactionView; import org.apache.ignite.transactions.TransactionConcurrency; import org.apache.ignite.transactions.TransactionIsolation; @@ -2432,7 +2434,7 @@ void txLocksInfo(UUID nodeId, TxDeadlockFuture fut, Set txKeys) { try { if (!cctx.localNodeId().equals(nodeId)) - req.prepareMarshal(cctx); + GridCacheMessageDeployer.deploy(cctx.kernalContext().messageFactory(), req, cctx); cctx.gridIO().sendToGridTopic(node, TOPIC_TX, req, SYSTEM_POOL); } @@ -3417,7 +3419,7 @@ private class DeadlockDetectionListener implements GridMessageListener { try { if (!cctx.localNodeId().equals(nodeId)) - res.prepareMarshal(cctx); + GridCacheMessageDeployer.deploy(cctx.kernalContext().messageFactory(), res, cctx); cctx.gridIO().sendToGridTopic(nodeId, TOPIC_TX, res, SYSTEM_POOL); } @@ -3502,7 +3504,8 @@ private void unmarshall(UUID nodeId, GridCacheMessage cacheMsg) { return; try { - cacheMsg.finishUnmarshal(cctx, cctx.deploy().globalLoader()); + MessageMarshaller.unmarshal(cctx.kernalContext().messageFactory(), + cacheMsg, cctx.kernalContext(), null, cctx.deploy().globalLoader()); } catch (IgniteCheckedException e) { cacheMsg.onClassError(e); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxEntryValueHolder.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxEntryValueHolder.java index 98e5830cb3b46..425e4d88cdfeb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxEntryValueHolder.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxEntryValueHolder.java @@ -17,11 +17,8 @@ package org.apache.ignite.internal.processors.cache.transactions; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.CacheObject; -import org.apache.ignite.internal.processors.cache.CacheObjectValueContext; -import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheOperation; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -119,25 +116,6 @@ public boolean hasReadValue() { return hasReadVal; } - /** - * @param ctx Cache context. - * @throws IgniteCheckedException If marshaling failed. - */ - public void marshal(GridCacheContext ctx) throws IgniteCheckedException { - if (hasWriteVal && val != null) - val.prepareMarshal(ctx.cacheObjectContext()); - } - - /** - * @param ctx Cache context. - * @param ldr Class loader. - * @throws IgniteCheckedException If unmarshalling failed. - */ - public void unmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { - if (hasWriteVal && val != null) - val.finishUnmarshal(ctx, ldr); - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(TxEntryValueHolder.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxLocksRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxLocksRequest.java index 4db908333d72b..3e2ba30b559ea 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxLocksRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxLocksRequest.java @@ -17,17 +17,14 @@ package org.apache.ignite.internal.processors.cache.transactions; -import java.util.Collection; import java.util.Set; -import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.MarshalledCollection; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.GridCacheMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.A; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; /** * Transactions lock list request. @@ -39,7 +36,8 @@ public class TxLocksRequest extends GridCacheMessage { /** Tx keys. */ @GridToStringInclude - private Set txKeys; + @MarshalledCollection("txKeysArr") + Set txKeys; /** Array of txKeys from {@link #txKeys}. Used during marshalling and unmarshalling. */ @GridToStringExclude @@ -71,10 +69,8 @@ public long futureId() { return futId; } - /** - * @return Tx keys. - */ - public Collection txKeys() { + /** */ + public Set txKeys() { return txKeys; } @@ -87,35 +83,4 @@ public Collection txKeys() { @Override public boolean addDeploymentInfo() { return addDepInfo; } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - txKeysArr = new IgniteTxKey[txKeys.size()]; - - int i = 0; - - for (IgniteTxKey key : txKeys) { - key.prepareMarshal(ctx.cacheContext(key.cacheId())); - - txKeysArr[i++] = key; - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - super.finishUnmarshal(ctx, ldr); - - txKeys = U.newHashSet(txKeysArr.length); - - for (IgniteTxKey key : txKeysArr) { - key.finishUnmarshal(ctx.cacheContext(key.cacheId()), ldr); - - txKeys.add(key); - } - - txKeysArr = null; - } - } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxLocksResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxLocksResponse.java index 8ebbcbddbd031..e2b9ed39a267d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxLocksResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxLocksResponse.java @@ -23,14 +23,13 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.MarshalledCollection; +import org.apache.ignite.internal.MarshalledMap; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.GridCacheMessage; -import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; /** * Transactions lock list response. @@ -42,11 +41,13 @@ public class TxLocksResponse extends GridCacheMessage { /** Locks for near txKeys of near transactions. */ @GridToStringInclude - private final Map> nearTxKeyLocks = new HashMap<>(); + @MarshalledMap(keys = "nearTxKeysArr", values = "locksArr") + final Map> nearTxKeyLocks = new HashMap<>(); /** Remote keys involved into transactions. Doesn't include near keys. */ @GridToStringInclude - private Set txKeys; + @MarshalledCollection("txKeysArr") + Set txKeys; /** Array of txKeys from {@link #nearTxKeyLocks}. Used during marshalling and unmarshalling. */ @GridToStringExclude @@ -96,7 +97,7 @@ public Map> txLocks() { * @return Lock list for given tx key. */ public List txLocks(IgniteTxKey txKey) { - return nearTxKeyLocks.get(txKey); + return txLocks().get(txKey); } /** @@ -135,77 +136,4 @@ public void addKey(IgniteTxKey key) { @Override public String toString() { return S.toString(TxLocksResponse.class, this); } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { - super.prepareMarshal(ctx); - - if (nearTxKeyLocks != null && !nearTxKeyLocks.isEmpty()) { - int len = nearTxKeyLocks.size(); - - nearTxKeysArr = new IgniteTxKey[len]; - locksArr = (List[])new List[len]; - - int i = 0; - - for (Map.Entry> entry : nearTxKeyLocks.entrySet()) { - IgniteTxKey key = entry.getKey(); - - key.prepareMarshal(ctx.cacheContext(key.cacheId())); - - nearTxKeysArr[i] = key; - locksArr[i] = entry.getValue(); - - i++; - } - } - - if (txKeys != null && !txKeys.isEmpty()) { - txKeysArr = new IgniteTxKey[txKeys.size()]; - - int i = 0; - - for (IgniteTxKey key : txKeys) { - key.prepareMarshal(ctx.cacheContext(key.cacheId())); - - txKeysArr[i++] = key; - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException { - try { - super.finishUnmarshal(ctx, ldr); - - if (nearTxKeysArr != null) { - for (int i = 0; i < nearTxKeysArr.length; i++) { - IgniteTxKey txKey = nearTxKeysArr[i]; - - txKey.key().finishUnmarshal(ctx.cacheObjectContext(txKey.cacheId()), ldr); - - txLocks().put(txKey, locksArr[i]); - } - - nearTxKeysArr = null; - locksArr = null; - } - - if (txKeysArr != null) { - txKeys = U.newHashSet(txKeysArr.length); - - for (IgniteTxKey txKey : txKeysArr) { - txKey.key().finishUnmarshal(ctx.cacheObjectContext(txKey.cacheId()), ldr); - - txKeys.add(txKey); - } - - txKeysArr = null; - } - } - catch (Exception e) { - throw new IgniteCheckedException(e); - } - } - } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/PartitionHashRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/PartitionHashRecord.java index 06ce5642fe874..49b938754087b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/PartitionHashRecord.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/PartitionHashRecord.java @@ -18,9 +18,8 @@ import java.io.Serializable; import java.util.Objects; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.configuration.BinaryConfiguration; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.binary.GridBinaryMarshaller; import org.apache.ignite.internal.management.cache.PartitionKey; @@ -28,15 +27,14 @@ import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.jetbrains.annotations.Nullable; /** * Record containing partition checksum, primary flag and consistent ID of owner. */ -public class PartitionHashRecord implements MarshallableMessage, Serializable { +public class PartitionHashRecord implements Message, Serializable { /** */ private static final long serialVersionUID = 0L; @@ -54,6 +52,7 @@ public class PartitionHashRecord implements MarshallableMessage, Serializable { /** Consistent id. */ @GridToStringInclude + @Marshalled("consistentIdBytes") Object consistentId; /** Bytes of {@link #consistentId}. */ @@ -73,6 +72,7 @@ public class PartitionHashRecord implements MarshallableMessage, Serializable { /** Update counter's state. */ @GridToStringInclude + @Marshalled("updateCntrBytes") Object updateCntr; /** Bytes of {@link #updateCntr}. */ @@ -248,27 +248,6 @@ public void hasExpiringEntries(boolean hasExpiringEntries) { this.hasExpiringEntries = hasExpiringEntries; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (consistentId != null) - consistentIdBytes = U.marshal(marsh, consistentId); - - if (updateCntr != null) - updateCntrBytes = U.marshal(marsh, updateCntr); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - if (consistentIdBytes != null) - consistentId = U.unmarshal(marsh, consistentIdBytes, clsLdr); - - if (updateCntrBytes != null) - updateCntr = U.unmarshal(marsh, updateCntrBytes, clsLdr); - - consistentId = null; - updateCntrBytes = null; - } - /** {@inheritDoc} */ @Override public String toString() { return size == MOVING_PARTITION_SIZE ? diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/TransactionsHashRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/TransactionsHashRecord.java index 38bd085377824..1aa7a72c2e1ec 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/TransactionsHashRecord.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/TransactionsHashRecord.java @@ -18,21 +18,20 @@ package org.apache.ignite.internal.processors.cache.verify; import java.io.Serializable; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; /** Represents committed transactions hash for a pair of nodes. */ -public class TransactionsHashRecord implements MarshallableMessage, Serializable { +public class TransactionsHashRecord implements Message, Serializable { /** */ private static final long serialVersionUID = 0L; /** Consistent ID of local node that participated in the transaction. This node produces this record. */ @GridToStringInclude + @Marshalled("locConsistentIdBytes") Object locConsistentId; /** Bytes of {@link #locConsistentId}. */ @@ -41,6 +40,7 @@ public class TransactionsHashRecord implements MarshallableMessage, Serializable /** Consistent ID of remote node that participated in the transactions. */ @GridToStringInclude + @Marshalled("rmtConsistentIdBytes") Object rmtConsistentId; /** Bytes of {@link #rmtConsistentId}. */ @@ -64,18 +64,6 @@ public TransactionsHashRecord(Object locConsistentId, Object rmtConsistentId, in this.txHash = txHash; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - locConsistentIdBytes = U.marshal(marsh, locConsistentId); - rmtConsistentIdBytes = U.marshal(marsh, rmtConsistentId); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - locConsistentId = U.unmarshal(marsh, locConsistentIdBytes, clsLdr); - rmtConsistentId = U.unmarshal(marsh, rmtConsistentIdBytes, clsLdr); - } - /** @return Committed transactions IDs hash. */ public int transactionHash() { return txHash; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ChangeGlobalStateMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ChangeGlobalStateMessage.java index 461d36f8bdb17..bf24db10164e9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ChangeGlobalStateMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ChangeGlobalStateMessage.java @@ -19,9 +19,8 @@ import java.util.List; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cluster.ClusterState; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.discovery.DiscoCache; import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage; @@ -32,15 +31,14 @@ import org.apache.ignite.internal.processors.service.ServiceDeploymentActions; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; /** * Message represent request for change cluster global state. */ -public class ChangeGlobalStateMessage extends DiscoveryCustomMessage implements MarshallableMessage { +public class ChangeGlobalStateMessage extends DiscoveryCustomMessage implements Message { /** Request ID */ @Order(0) UUID reqId; @@ -58,7 +56,8 @@ public class ChangeGlobalStateMessage extends DiscoveryCustomMessage implements List storedCfgs; /** */ - @Nullable private BaselineTopology baselineTopology; + @Nullable @Marshalled("baselineTopologyBytes") + BaselineTopology baselineTopology; /** JDK Serialized version of baselineTopology. */ @Order(4) @@ -221,18 +220,6 @@ public UUID requestId() { return reqId; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (baselineTopology != null) - baselineTopologyBytes = U.marshal(marsh, baselineTopology); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - if (baselineTopologyBytes != null) - baselineTopology = U.unmarshal(marsh, baselineTopologyBytes, clsLdr); - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(ChangeGlobalStateMessage.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java index 3b75f2baf09fb..85678108bd3b3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java @@ -76,6 +76,7 @@ import org.apache.ignite.metric.MetricRegistry; import org.apache.ignite.mxbean.IgniteClusterMXBean; import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.spi.discovery.DiscoveryDataBag; import org.apache.ignite.spi.discovery.DiscoveryDataBag.GridDiscoveryData; import org.apache.ignite.spi.discovery.DiscoveryMetricsProvider; @@ -379,6 +380,13 @@ public void initDiagnosticListeners() throws IgniteCheckedException { if (msg instanceof IgniteDiagnosticRequest) { IgniteDiagnosticRequest infoReq = (IgniteDiagnosticRequest)msg; + try { + MessageMarshaller.unmarshal(ctx.messageFactory(), infoReq, ctx, null, U.gridClassLoader()); + } + catch (IgniteCheckedException e) { + U.error(diagnosticLog, "Failed to ummarshall diagnostic request [msg=" + infoReq + "]", e); + } + ClusterNode node = ctx.discovery().node(nodeId); if (node == null) { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java index 7291e631c2f31..efc65d8d35431 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java @@ -975,7 +975,7 @@ private AbstractContinuousMessage createStartMessage(UUID routineId, reqData.deploymentInfo(dep); } - reqData.prepareMarshal(ctx); + reqData.marshal(ctx); if (!immutableDiscoCustomMsg) { StartRoutineDiscoveryMessage msg = new StartRoutineDiscoveryMessage(routineId, reqData, Mode.MUTABLE); @@ -1342,7 +1342,7 @@ private void processStartRequestMutable(ClusterNode node, StartRoutineDiscoveryM IgniteCheckedException err = null; try { - data.finishUnmarshal(ctx, node.id()); + data.unmarshal(ctx, node.id()); } catch (IgniteCheckedException e) { U.error(log, "Failed to unmarshal start request data [nodeId=" + node.id() + @@ -1484,7 +1484,7 @@ private void processStartRequestImmutable(final AffinityTopologyVersion topVer, Exception err = null; try { - reqData.finishUnmarshal(ctx, snd.id()); + reqData.unmarshal(ctx, snd.id()); } catch (IgniteCheckedException e) { err = e; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRequestData.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRequestData.java index 99c39201500af..9571c231bbf9a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRequestData.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRequestData.java @@ -171,7 +171,7 @@ public void autoUnsubscribe(boolean autoUnsubscribe) { } /** */ - public void prepareMarshal(GridKernalContext ctx) throws IgniteCheckedException { + public void marshal(GridKernalContext ctx) throws IgniteCheckedException { if (hnd != null) { if (ctx.config().isPeerClassLoadingEnabled()) { // Handle peer deployment for other handler-specific objects. @@ -186,7 +186,7 @@ public void prepareMarshal(GridKernalContext ctx) throws IgniteCheckedException } /** */ - public void finishUnmarshal(GridKernalContext ctx, UUID sndId) throws IgniteCheckedException { + public void unmarshal(GridKernalContext ctx, UUID sndId) throws IgniteCheckedException { if (ctx.config().isPeerClassLoadingEnabled() && clsName != null) { GridDeployment dep = ctx.deploy().getGlobalDeployment(depInfo.deployMode(), clsName, diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java index 1b795b2faf84a..9a030b8e3354f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java @@ -1931,12 +1931,12 @@ private void submit( else { try { for (DataStreamerEntry e : entries) { - e.getKey().prepareMarshal(cacheObjCtx); + e.getKey().marshal(cacheObjCtx); CacheObject val = e.getValue(); if (val != null) - val.prepareMarshal(cacheObjCtx); + val.marshal(cacheObjCtx); } if (updaterBytes == null) { @@ -2253,7 +2253,7 @@ protected static class IsolatedUpdater implements StreamReceiver { final GridCacheContext cctx = cache.context(); for (DataStreamerEntry e : col) { - e.getKey().finishUnmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader()); + e.getKey().unmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader()); CacheObject val = e.getValue(); if (val != null) { checkSecurityPermission(SecurityPermission.CACHE_PUT); - val.finishUnmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader()); + val.unmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader()); } else checkSecurityPermission(SecurityPermission.CACHE_REMOVE); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobProcessor.java index 3e584ed0e4842..ec0096383bf2b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobProcessor.java @@ -1250,7 +1250,7 @@ public void processJobExecuteRequest(ClusterNode node, final GridJobExecuteReque try { if (!loc) - req.finishUnmarshal(marsh, U.resolveClassLoader(dep.classLoader(), ctx.config())); + req.unmarshal(marsh, U.resolveClassLoader(dep.classLoader(), ctx.config())); // Note that we unmarshal session/job attributes here with proper class loader. GridTaskSessionImpl taskSes = ctx.session().createTaskSession( diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageCasMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageCasMessage.java index d40661bbadcad..95f3717fb5b63 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageCasMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageCasMessage.java @@ -75,16 +75,16 @@ public boolean matches() { } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - super.prepareMarshal(marsh); + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { + super.marshal(marsh); if (expVal != null && expValBytes == null) expValBytes = U.marshal(marsh, expVal); } /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh) throws IgniteCheckedException { - super.finishUnmarshal(marsh); + @Override public void unmarshal(Marshaller marsh) throws IgniteCheckedException { + super.unmarshal(marsh); if (expValBytes != null && expVal == null) expVal = U.unmarshal(marsh, expValBytes, U.gridClassLoader()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java index ad9022f2e9747..990a26d9b2386 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageImpl.java @@ -1018,7 +1018,7 @@ private GridFutureAdapter startWrite(String key, @Nullable Serializable val) DistributedMetaStorageUpdateMessage msg = new DistributedMetaStorageUpdateMessage(reqId, key, val); - msg.prepareMarshal(marshaller); + msg.marshal(marshaller); ctx.discovery().sendCustomEvent(msg); @@ -1039,7 +1039,7 @@ private GridFutureAdapter startCas(String key, @Nullable Serializable e DistributedMetaStorageCasMessage msg = new DistributedMetaStorageCasMessage(reqId, key, expVal, newVal); - msg.prepareMarshal(marshaller); + msg.marshal(marshaller); ctx.discovery().sendCustomEvent(msg); @@ -1281,7 +1281,7 @@ private void completeCas( Serializable oldVal = bridge.read(msg.key()); - msg.finishUnmarshal(marshaller); + msg.unmarshal(marshaller); if (!Objects.deepEquals(oldVal, msg.expectedValue())) { msg.setMatches(false); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageUpdateMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageUpdateMessage.java index b836fec1032d6..07e645795c6e7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageUpdateMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/metastorage/persistence/DistributedMetaStorageUpdateMessage.java @@ -84,13 +84,13 @@ public byte[] valueBytes() { } /** @param marsh Marshaller. */ - public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { + public void marshal(Marshaller marsh) throws IgniteCheckedException { if (val != null && valBytes == null) valBytes = U.marshal(marsh, val); } /** @param marsh Marshaller. */ - public void finishUnmarshal(Marshaller marsh) throws IgniteCheckedException { + public void unmarshal(Marshaller marsh) throws IgniteCheckedException { // No-op. } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/PluginsDataBagItem.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/PluginsDataBagItem.java index 9b70e42223788..64860f731f0d2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/PluginsDataBagItem.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/plugin/PluginsDataBagItem.java @@ -19,17 +19,15 @@ import java.io.Serializable; import java.util.Map; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.util.typedef.F; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; /** */ -public class PluginsDataBagItem implements MarshallableMessage { +public class PluginsDataBagItem implements Message { /** Original plugins data. */ + @Marshalled("dataBytes") @Nullable Map data; /** Serialized plugins data. */ @@ -44,18 +42,6 @@ public PluginsDataBagItem(@Nullable Map data) { this.data = data; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (!F.isEmpty(data)) - dataBytes = U.marshal(marsh, data); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - if (dataBytes != null) - data = U.unmarshal(marsh, dataBytes, clsLdr); - } - /** @return Original plugins data. */ public @Nullable Map data() { return data; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java index ebb23aff57ea9..606c117e0a162 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java @@ -19,22 +19,21 @@ import java.util.Collection; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.QueryEntity; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; /** * Enabling indexing on cache operation. */ -public class SchemaAddQueryEntityOperation extends SchemaAbstractOperation implements MarshallableMessage { +public class SchemaAddQueryEntityOperation extends SchemaAbstractOperation implements Message { /** */ private static final long serialVersionUID = 0L; /** */ - private Collection entities; + @Marshalled("qryEntitiesBytes") + Collection entities; /** Serialized form of query entities. */ @Order(0) @@ -93,20 +92,4 @@ public int queryParallelism() { public boolean isSqlEscape() { return sqlEscape; } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (entities != null) - qryEntitiesBytes = U.marshal(marsh, entities); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - if (qryEntitiesBytes != null) { - entities = U.unmarshal(marsh, qryEntitiesBytes, clsLdr); - - qryEntitiesBytes = null; - } - } - } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/task/GridTaskResultResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/task/GridTaskResultResponse.java index ff0f3af4ffce8..32b6ef00ba5ff 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/task/GridTaskResultResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/task/GridTaskResultResponse.java @@ -17,18 +17,17 @@ package org.apache.ignite.internal.processors.rest.handlers.task; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; /** * Task result response. */ -public class GridTaskResultResponse implements MarshallableMessage { +public class GridTaskResultResponse implements Message { /** Result. */ + @Marshalled("resBytes") public @Nullable Object res; /** Serialized result. */ @@ -96,19 +95,4 @@ public void error(String err) { this.err = err; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (res != null) - resBytes = U.marshal(marsh, res); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - if (resBytes != null) { - res = U.unmarshal(marsh, resBytes, clsLdr); - - // It is not required anymore. - resBytes = null; - } - } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceDeploymentRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceDeploymentRequest.java index 7d67164f10be0..b58c0968ce3b7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceDeploymentRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceDeploymentRequest.java @@ -17,22 +17,21 @@ package org.apache.ignite.internal.processors.service; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.jetbrains.annotations.NotNull; /** * Service deployment request. */ -public class ServiceDeploymentRequest extends ServiceChangeAbstractRequest implements MarshallableMessage { +public class ServiceDeploymentRequest extends ServiceChangeAbstractRequest implements Message { /** Service configuration. */ - private LazyServiceConfiguration cfg; + @Marshalled("cfgBytes") + LazyServiceConfiguration cfg; /** JDK serialization for {@link #cfg}. */ @Order(0) @@ -58,18 +57,6 @@ public LazyServiceConfiguration configuration() { return cfg; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (cfg != null) - cfgBytes = U.marshal(marsh, cfg); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - if (cfgBytes != null) - cfg = U.unmarshal(marsh, cfgBytes, clsLdr); - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(ServiceDeploymentRequest.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceSingleNodeDeploymentResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceSingleNodeDeploymentResult.java index 10ceefb8284aa..cefe1ae00f9f6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceSingleNodeDeploymentResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceSingleNodeDeploymentResult.java @@ -18,6 +18,7 @@ package org.apache.ignite.internal.processors.service; import java.io.Serializable; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import org.apache.ignite.internal.Order; @@ -76,8 +77,14 @@ public Collection errors() { * @param errors Exceptions. */ public void errors(@Nullable Collection errors) { - if (!F.isEmpty(errors)) - this.errors = F.viewReadOnly(errors, ErrorMessage::new); + if (errors == null) + return; + + this.errors = new ArrayList<>(); + + for (Throwable th : errors) { + this.errors.add(new ErrorMessage(th)); + } } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/task/GridTaskWorker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/task/GridTaskWorker.java index d21de03723432..fe419cefaf637 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/task/GridTaskWorker.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/task/GridTaskWorker.java @@ -1416,7 +1416,7 @@ private void sendRequest(ComputeJobResult res) { if (loc) ctx.job().processJobExecuteRequest(ctx.discovery().localNode(), req); else { - req.prepareMarshal(marsh); + req.marshal(marsh); byte plc; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java index faf416dfdbee7..a8331346de417 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java @@ -85,11 +85,9 @@ public GridDirectParser(IgniteLogger log, MessageFactory msgFactory, GridNioMess boolean finished = false; if (msg != null && buf.hasRemaining()) { - MessageSerializer msgSer = msgFactory.serializer(msg.directType()); - reader.setBuffer(buf); - finished = msgSer.readFrom(msg, reader); + finished = MessageSerializer.readFrom(msgFactory, msg, reader); } if (finished) { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java index 797290677db52..69b5c76f45b2c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java @@ -1648,11 +1648,9 @@ private boolean writeToBuffer( finished = ((ClientMessage)msg).writeTo(buf); } else { - MessageSerializer msgSer = messageFactory().serializer(msg.directType()); - writer.setBuffer(buf); - finished = msgSer.writeTo(msg, writer); + finished = MessageSerializer.writeTo(messageFactory(), msg, writer); } span.addTag(SOCKET_WRITE_BYTES, () -> Integer.toString(buf.position() - startPos)); @@ -1849,11 +1847,9 @@ private boolean writeToBuffer(GridSelectorNioSessionImpl ses, ByteBuffer buf, Se finished = ((ClientMessage)msg).writeTo(buf); } else { - MessageSerializer msgSer = msgFactory.serializer(msg.directType()); - writer.setBuffer(buf); - finished = msgSer.writeTo(msg, writer); + finished = MessageSerializer.writeTo(msgFactory, msg, writer); } span.addTag(SOCKET_WRITE_BYTES, () -> Integer.toString(buf.position() - startPos)); diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/CacheIdAware.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/CacheIdAware.java new file mode 100644 index 0000000000000..005e0c4652f00 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/CacheIdAware.java @@ -0,0 +1,24 @@ +/* + * 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.plugin.extensions.communication; + +/** Implemented by messages that carry a cache ID identifying the target cache. */ +public interface CacheIdAware { + /** @return Cache ID identifying the target cache. */ + public int cacheId(); +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/MarshallableMessage.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MarshallableMessage.java similarity index 64% rename from modules/core/src/main/java/org/apache/ignite/internal/MarshallableMessage.java rename to modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MarshallableMessage.java index 72b67ab2c4afd..06f84b11d9cd4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/MarshallableMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MarshallableMessage.java @@ -15,20 +15,19 @@ * limitations under the License. */ -package org.apache.ignite.internal; +package org.apache.ignite.plugin.extensions.communication; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.marshaller.Marshaller; -import org.apache.ignite.plugin.extensions.communication.Message; -/** A {@link Message} which still requires external custom pre-marshalling and post-unmarshalling. */ +/** A {@link Message} requiring a custom marshal/unmarshal step via {@link Marshaller}. */ public interface MarshallableMessage extends Message { - /** @param marsh External custom marshaller. */ - public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException; + /** @param marsh Marshaller for marshalling. */ + public void marshal(Marshaller marsh) throws IgniteCheckedException; /** - * @param marsh External custom marshaller. - * @param clsLdr External class loader to post-unmarshall. + * @param marsh Marshaller for unmarshalling. + * @param clsLdr Class loader for unmarshalling. */ - public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException; + public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException; } diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java index 1e4abc845c52c..5f88e10e22510 100644 --- a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java +++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java @@ -24,6 +24,21 @@ /** * Base class for all communication messages. + *

+ * Wire fields are declared by annotating instance fields; {@link org.apache.ignite.internal.MessageProcessor} then + * generates the serializer, so implementations should not hand-write {@code writeTo}/{@code readFrom}. Available + * field annotations (see each annotation's javadoc for details): + *

    + *
  • {@link org.apache.ignite.internal.Order @Order} — an ordered wire field (the basic building block);
  • + *
  • {@link org.apache.ignite.internal.Compress @Compress} — compress the field's wire form;
  • + *
  • {@link org.apache.ignite.internal.NioField @NioField} — a low-level NIO field;
  • + *
  • {@link org.apache.ignite.internal.CustomMapper @CustomMapper} — map the field via a custom mapper;
  • + *
  • {@link org.apache.ignite.internal.Marshalled @Marshalled} / + * {@link org.apache.ignite.internal.MarshalledMap @MarshalledMap} / + * {@link org.apache.ignite.internal.MarshalledCollection @MarshalledCollection} / + * {@link org.apache.ignite.internal.MarshalledObjects @MarshalledObjects} — for {@link MarshallableMessage} + * payloads serialized via a {@link org.apache.ignite.marshaller.Marshaller}.
  • + *
*/ public interface Message { /** Direct type size in bytes. */ @@ -32,19 +47,25 @@ public interface Message { /** Registry of message class to direct type mappings, populated during factory initialization. */ Map, Short> REGISTRATIONS = new ConcurrentHashMap<>(); + /** Per-class cache over {@link #REGISTRATIONS}; keeps {@link #directType()} off the hash lookup on the hot path. */ + ClassValue DIRECT_TYPES = new ClassValue<>() { + @Override protected Short computeValue(Class type) { + Short directType = REGISTRATIONS.get(type); + + if (directType == null) + throw new UnknownMessageException(type.asSubclass(Message.class)); + + return directType; + } + }; + /** * Gets message type. * * @return Message type. */ default short directType() { - var clazz = getClass(); - Short type = REGISTRATIONS.get(clazz); - - if (type == null) - throw new UnknownMessageException(clazz); - - return type; + return DIRECT_TYPES.get(getClass()); } /** diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFactory.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFactory.java index 53366108bfca0..5c8e863a1030d 100644 --- a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFactory.java @@ -19,6 +19,8 @@ import java.util.function.Supplier; import org.apache.ignite.IgniteException; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; +import org.jetbrains.annotations.Nullable; /** * Message factory for all communication messages registered using {@link #register(short, Supplier, MessageSerializer)} method call. @@ -31,80 +33,97 @@ public interface MessageFactory { * * @param directType Direct type. * @param supplier Message factory. + * @param serializer Message serializer. * @throws IgniteException In case of attempt to register message with direct type which is already registered. * @throws IllegalStateException On any invocation of this method when class which implements this interface * is alredy constructed. - * @deprecated Use {@link #register(short, Supplier, MessageSerializer)} instead. */ - @Deprecated(forRemoval = true) - default void register(short directType, Supplier supplier) throws IgniteException { - throw new UnsupportedOperationException(); + default void register(short directType, Supplier supplier, MessageSerializer serializer) throws IgniteException { + register(directType, supplier, serializer, null, null); } /** - * Register message factory with given direct type. All messages must be registered during construction + * Register message factory with given direct type and serializer. The direct type is also registered + * on the message class via {@link Message#registerAsDirectType(short)} so that {@link Message#directType()} + * resolves automatically without requiring each message to override it. + * + *

This is the preferred registration method. All messages must be registered during construction * of class which implements this interface. Any invocation of this method after initialization is done must * throw {@link IllegalStateException} exception. * * @param directType Direct type. * @param supplier Message factory. + * @param serializer Message serializer. * @throws IgniteException In case of attempt to register message with direct type which is already registered. * @throws IllegalStateException On any invocation of this method when class which implements this interface - * is alredy constructed. - * @deprecated Use {@link #register(int, Supplier, MessageSerializer)} instead. + * is already constructed. */ - @Deprecated(forRemoval = true) - default void register(int directType, Supplier supplier) throws IgniteException { - register((short)directType, supplier); + default void register(int directType, Supplier supplier, MessageSerializer serializer) throws IgniteException { + register((short)directType, supplier, serializer); } /** - * Register message factory with given direct type. All messages must be registered during construction - * of class which implements this interface. Any invocation of this method after initialization is done must - * throw {@link IllegalStateException} exception. + * Creates new message instance of provided type. + * + * @param type Message type. + * @return Message instance. + */ + public Message create(short type); + + /** + * Register message factory with given direct type, serializer, and marshaller. All messages must be registered + * during construction of class which implements this interface. * * @param directType Direct type. * @param supplier Message factory. * @param serializer Message serializer. + * @param marshaller Message marshaller, or {@code null} for non-marshallable messages. * @throws IgniteException In case of attempt to register message with direct type which is already registered. - * @throws IllegalStateException On any invocation of this method when class which implements this interface - * is alredy constructed. */ - public void register(short directType, Supplier supplier, MessageSerializer serializer) throws IgniteException; + default void register(short directType, Supplier supplier, MessageSerializer serializer, + @Nullable MessageMarshaller marshaller) throws IgniteException { + register(directType, supplier, serializer, marshaller, null); + } /** - * Register message factory with given direct type and serializer. The direct type is also registered - * on the message class via {@link Message#registerAsDirectType(short)} so that {@link Message#directType()} - * resolves automatically without requiring each message to override it. - * - *

This is the preferred registration method. All messages must be registered during construction - * of class which implements this interface. Any invocation of this method after initialization is done must - * throw {@link IllegalStateException} exception. + * Register message factory with given direct type, serializer, marshaller, and deployer. All messages must be + * registered during construction of class which implements this interface. * * @param directType Direct type. * @param supplier Message factory. * @param serializer Message serializer. + * @param marshaller Message marshaller, or {@code null} for non-marshallable messages. + * @param deployer Message deployer, or {@code null} for messages without deployable fields. * @throws IgniteException In case of attempt to register message with direct type which is already registered. - * @throws IllegalStateException On any invocation of this method when class which implements this interface - * is already constructed. */ - default void register(int directType, Supplier supplier, MessageSerializer serializer) throws IgniteException { - register((short)directType, supplier, serializer); - } + public void register(short directType, Supplier supplier, MessageSerializer serializer, + @Nullable MessageMarshaller marshaller, @Nullable GridCacheMessageDeployer deployer) throws IgniteException; /** - * Creates new message instance of provided type. + * Returns {@code MessageSerializer} for provided type. * * @param type Message type. - * @return Message instance. + * @return Message serializer. */ - public Message create(short type); + public MessageSerializer serializer(short type); /** - * Returns {@code MessageSerializer} for provided type. + * Returns {@code MessageMarshaller} for provided type, or {@code null} if none is registered + * (e.g. for {@code NonMarshallableMessage} types). * * @param type Message type. - * @return Message instance. + * @return Message marshaller, or {@code null}. */ - public MessageSerializer serializer(short type); + public @Nullable MessageMarshaller marshaller(short type); + + /** + * Returns {@code GridCacheMessageDeployer} for provided type, or {@code null} if none is registered + * (e.g. for messages without deployable fields). + * + * @param type Message type. + * @return Message deployer, or {@code null}. + */ + default @Nullable GridCacheMessageDeployer deployer(short type) { + return null; + } } diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageMarshaller.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageMarshaller.java new file mode 100644 index 0000000000000..ecbc908fd2c07 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageMarshaller.java @@ -0,0 +1,233 @@ +/* + * 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.plugin.extensions.communication; + +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteSystemProperties; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.jetbrains.annotations.Nullable; + +/** + * Handles {@code marshal}/{@code unmarshal} for a {@link Message} type that requires custom serialization. + * + * @param Message type. + */ +public interface MessageMarshaller { + /** + * Marshals the message on the user thread before sending. + * + * @param msg Message to marshal. + * @param kctx Kernal context. + * @param nested Cache object context, or {@code null} if not applicable. + */ + public void marshal(M msg, GridKernalContext kctx, @Nullable CacheObjectContext nested) + throws IgniteCheckedException; + + /** + * Unmarshals the message with full cache context and class loader. + * + * @param msg Message to unmarshal. + * @param kctx Kernal context. + * @param nested Cache object context, or {@code null} if not applicable. + * @param clsLdr Class loader for unmarshalling. + */ + public void unmarshal(M msg, GridKernalContext kctx, @Nullable CacheObjectContext nested, ClassLoader clsLdr) + throws IgniteCheckedException; + + /** + * Unmarshals message fields that do not require a cache context. + * + * @param msg Message to unmarshal. + * @param kctx Kernal context. + */ + public void unmarshal(M msg, GridKernalContext kctx) throws IgniteCheckedException; + + /** + * Unmarshals only {@code @NioField}-annotated fields in the NIO/IO thread. No-op by default. + * + * @param msg Message to unmarshal. + * @param kctx Kernal context. + */ + default void unmarshalNio(M msg, GridKernalContext kctx) throws IgniteCheckedException { + } + + /** + * Null-safe {@code unmarshalNio} — skips when no marshaller is registered. + * + * @param Message type. + * @param factory Message factory. + * @param msg Message to unmarshal. + * @param kctx Kernal context. + */ + static void unmarshalNio(MessageFactory factory, M msg, GridKernalContext kctx) + throws IgniteCheckedException { + MessageMarshaller m = resolve(factory, msg); + + if (m != null) + m.unmarshalNio(msg, kctx); + } + + /** + * Null-safe {@code marshal} — skips when no marshaller is registered. + * + * @param Message type. + * @param factory Message factory. + * @param msg Message to marshal. + * @param kctx Kernal context. + * @param nested Cache object context, or {@code null} if not applicable. + */ + static void marshal(MessageFactory factory, M msg, GridKernalContext kctx, + @Nullable CacheObjectContext nested) throws IgniteCheckedException { + MessageMarshaller m = resolve(factory, msg); + + if (m != null) + m.marshal(msg, kctx, nested); + } + + /** + * Null-safe {@code unmarshal} — skips when no marshaller is registered. + * + * @param Message type. + * @param factory Message factory. + * @param msg Message to unmarshal. + * @param kctx Kernal context. + * @param nested Cache object context, or {@code null} if not applicable. + * @param clsLdr Class loader for unmarshalling. + */ + static void unmarshal(MessageFactory factory, M msg, GridKernalContext kctx, + @Nullable CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + assert !Dedup.ENABLED || Dedup.firstUnmarshal(msg, true) : "Finish-unmarshalled more than once: " + msg.getClass().getName(); + + MessageMarshaller m = resolve(factory, msg); + + if (m != null) + m.unmarshal(msg, kctx, nested, clsLdr); + } + + /** + * Null-safe {@code unmarshal} (cache-free) — skips when no marshaller is registered. + * + * @param Message type. + * @param factory Message factory. + * @param msg Message to unmarshal. + * @param kctx Kernal context. + */ + static void unmarshal(MessageFactory factory, M msg, GridKernalContext kctx) + throws IgniteCheckedException { + assert !Dedup.ENABLED || Dedup.firstUnmarshal(msg, false) : "Finish-unmarshalled more than once: " + msg.getClass().getName(); + + MessageMarshaller m = resolve(factory, msg); + + if (m != null) + m.unmarshal(msg, kctx); + } + + /** @return the marshaller registered for {@code msg}'s direct type, or {@code null} if none. */ + @SuppressWarnings("unchecked") + private static MessageMarshaller resolve(MessageFactory factory, M msg) { + return (MessageMarshaller)factory.marshaller(msg.directType()); + } + + /** + * Detects a {@link MarshallableMessage} instance being finish-unmarshalled more than once within the same pass + * (cache-aware or cache-free) — a class-loader or receive-path bug. The two passes over one message (e.g. the + * generic {@code GridIoManager} pass plus a subsystem's cache-aware pass) are legitimate and tracked separately. + * Gated by {@link #ENABLED}, so it runs only under tests and is folded away in production. + */ + class Dedup { + /** + * When {@code true}, the no-double-unmarshal check runs. {@code static final} so the JIT folds the guard away + * in production (even with assertions on); enabled only by tests via {@code IGNITE_MESSAGE_UNMARSHAL_ONCE_CHECK}. + */ + static final boolean ENABLED = IgniteSystemProperties.getBoolean(IgniteSystemProperties.IGNITE_MESSAGE_UNMARSHAL_ONCE_CHECK); + + /** Queue of collected referents, drained on each call to evict stale {@link IdRef}s from {@link #SEEN}. */ + private static final ReferenceQueue Q = new ReferenceQueue<>(); + + /** Finish-unmarshalled instances, held weakly and keyed by identity so they vanish with the message. */ + private static final Set SEEN = ConcurrentHashMap.newKeySet(); + + /** */ + private Dedup() { + // No-op. + } + + /** + * @param msg Message about to be finish-unmarshalled. + * @param cacheMode {@code true} for the cache-aware pass, {@code false} for the cache-free pass; the two passes + * over one message are legitimate and tracked separately, so only a repeat of the same pass is reported. + * @return {@code true} if {@code msg} is not a {@link MarshallableMessage} or is finish-unmarshalled the first + * time in this pass. + */ + static boolean firstUnmarshal(Message msg, boolean cacheMode) { + if (!(msg instanceof MarshallableMessage)) + return true; + + for (Reference r; (r = Q.poll()) != null; ) + SEEN.remove(r); + + return SEEN.add(new IdRef(msg, cacheMode)); + } + + /** Weak reference to a message keyed by (identity, pass), so distinct messages and the two passes stay distinct. */ + private static final class IdRef extends WeakReference { + /** Referent identity hash folded with the pass, captured up front since the referent may be cleared later. */ + private final int hash; + + /** Unmarshal pass: cache-aware vs cache-free. Keeps the two legitimate passes over one message distinct. */ + private final boolean cacheMode; + + /** + * @param msg Tracked message. + * @param cacheMode Unmarshal pass. + */ + IdRef(Message msg, boolean cacheMode) { + super(msg, Q); + + this.cacheMode = cacheMode; + hash = 31 * System.identityHashCode(msg) + (cacheMode ? 1 : 0); + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return hash; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof IdRef)) + return false; + + IdRef ref = (IdRef)o; + + Message m = get(); + + return m != null && m == ref.get() && cacheMode == ref.cacheMode; + } + } + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageSerializer.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageSerializer.java index 90df0601693c3..28d6c6a62a053 100644 --- a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageSerializer.java +++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageSerializer.java @@ -38,4 +38,36 @@ public interface MessageSerializer { * @return Whether message was fully read. */ public boolean readFrom(M msg, MessageReader reader); + + /** + * Writes the message using the serializer resolved from the factory. + * + * @param factory Message factory. + * @param msg Message instance. + * @param writer Writer. + * @param Message type. + * @return Whether message was fully written. + */ + static boolean writeTo(MessageFactory factory, M msg, MessageWriter writer) { + return resolve(factory, msg).writeTo(msg, writer); + } + + /** + * Reads the message using the serializer resolved from the factory. + * + * @param factory Message factory. + * @param msg Message instance. + * @param reader Reader. + * @param Message type. + * @return Whether message was fully read. + */ + static boolean readFrom(MessageFactory factory, M msg, MessageReader reader) { + return resolve(factory, msg).readFrom(msg, reader); + } + + /** @return the serializer registered for {@code msg}'s direct type. */ + @SuppressWarnings("unchecked") + private static MessageSerializer resolve(MessageFactory factory, M msg) { + return (MessageSerializer)factory.serializer(msg.directType()); + } } diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/NonMarshallableMessage.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/NonMarshallableMessage.java new file mode 100644 index 0000000000000..8be7c31bd8211 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/NonMarshallableMessage.java @@ -0,0 +1,22 @@ +/* + * 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.plugin.extensions.communication; + +/** Marker interface: no {@link MessageMarshaller} is generated for implementing classes. */ +public interface NonMarshallableMessage extends Message { +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java index bbf821e17d799..552d5681bbf29 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java @@ -40,6 +40,7 @@ import org.apache.ignite.internal.IgniteNodeAttributes; import org.apache.ignite.internal.managers.communication.GridMessageListener; import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; import org.apache.ignite.internal.processors.timeout.GridSpiTimeoutObject; import org.apache.ignite.internal.util.IgniteExceptionRegistry; import org.apache.ignite.internal.util.typedef.internal.SB; @@ -49,6 +50,7 @@ import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFormatter; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.plugin.extensions.communication.MessageReader; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.plugin.extensions.communication.MessageWriter; @@ -755,12 +757,8 @@ private class GridDummySpiContext implements IgniteSpiContext { if (msgFactory0 == null) { msgFactory0 = new MessageFactory() { - @Override public void register(short directType, Supplier supplier) throws IgniteException { - throw new IgniteException("Failed to register message, node is not started."); - } - - @Override public void register(short directType, Supplier supplier, - MessageSerializer serializer) throws IgniteException { + @Override public void register(short directType, Supplier supplier, MessageSerializer serializer, + @Nullable MessageMarshaller marshaller, @Nullable GridCacheMessageDeployer deployer) throws IgniteException { throw new IgniteException("Failed to register message, node is not started."); } @@ -771,6 +769,10 @@ private class GridDummySpiContext implements IgniteSpiContext { @Override public MessageSerializer serializer(short type) { throw new IgniteException("Failed to register message, node is not started."); } + + @Nullable @Override public MessageMarshaller marshaller(short type) { + throw new IgniteException("Failed to register message, node is not started."); + } }; } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/internal/GridNioServerWrapper.java b/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/internal/GridNioServerWrapper.java index df7935c6c2f41..0a28e0c565499 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/internal/GridNioServerWrapper.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/internal/GridNioServerWrapper.java @@ -55,6 +55,7 @@ import org.apache.ignite.internal.direct.DirectMessageWriter; import org.apache.ignite.internal.managers.GridManager; import org.apache.ignite.internal.managers.tracing.GridTracingManager; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; import org.apache.ignite.internal.processors.metric.GridMetricManager; import org.apache.ignite.internal.processors.tracing.Tracing; import org.apache.ignite.internal.util.GridConcurrentFactory; @@ -87,6 +88,7 @@ import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFormatter; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.plugin.extensions.communication.MessageReader; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.plugin.extensions.communication.MessageWriter; @@ -814,9 +816,9 @@ public GridNioServer resetNioServer() throws IgniteCheckedException { MessageFactory msgFactory = new MessageFactory() { private MessageFactory impl; - @Override public void register(short directType, Supplier supplier, - MessageSerializer serializer) throws IgniteException { - get().register(directType, supplier, serializer); + @Override public void register(short directType, Supplier supplier, MessageSerializer serializer, + @Nullable MessageMarshaller marshaller, @Nullable GridCacheMessageDeployer deployer) throws IgniteException { + get().register(directType, supplier, serializer, marshaller, deployer); } @Nullable @Override public Message create(short type) { @@ -831,6 +833,10 @@ public GridNioServer resetNioServer() throws IgniteCheckedException { return get().serializer(type); } + @Nullable @Override public MessageMarshaller marshaller(short type) { + return get().marshaller(type); + } + private MessageFactory get() { if (impl == null) { impl = stateProvider.getSpiContext().messageFactory(); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/internal/TcpHandshakeExecutor.java b/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/internal/TcpHandshakeExecutor.java index 7a609d2f7ebdf..e7c8524807e60 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/internal/TcpHandshakeExecutor.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/internal/TcpHandshakeExecutor.java @@ -31,12 +31,12 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.plugin.extensions.communication.MessageWriter; import org.apache.ignite.spi.IgniteSpiContext; import org.apache.ignite.spi.communication.tcp.messages.HandshakeMessage; import org.apache.ignite.spi.communication.tcp.messages.NodeIdMessage; import org.apache.ignite.spi.communication.tcp.messages.RecoveryLastReceivedMessage; -import org.apache.ignite.spi.communication.tcp.messages.RecoveryLastReceivedMessageSerializer; import org.jetbrains.annotations.Nullable; import static org.apache.ignite.plugin.extensions.communication.Message.DIRECT_TYPE_SIZE; @@ -172,7 +172,7 @@ private abstract static class BlockingTransport { NodeIdMessage nodeIdMsg = new NodeIdMessage(); reader.setBuffer(buf); - msgFactory.serializer(nodeIdMsg.directType()).readFrom(nodeIdMsg, reader); + MessageSerializer.readFrom(msgFactory, nodeIdMsg, reader); reader.reset(); return nodeIdMsg.nodeId(); @@ -191,7 +191,7 @@ void sendHandshake(HandshakeMessage msg) throws IgniteCheckedException { writer.setBuffer(buf); - msgFactory.serializer(msg.directType()).writeTo(msg, writer); + MessageSerializer.writeTo(msgFactory, msg, writer); buf.flip(); @@ -210,8 +210,6 @@ long receiveAcknowledge() throws IgniteCheckedException { boolean fininshed = false; RecoveryLastReceivedMessage msg = new RecoveryLastReceivedMessage(); - RecoveryLastReceivedMessageSerializer msgSer = - (RecoveryLastReceivedMessageSerializer)msgFactory.serializer(msg.directType()); short msgType = 0; int readPos = 0; @@ -243,7 +241,7 @@ long receiveAcknowledge() throws IgniteCheckedException { reader.setBuffer(buf); - fininshed = msgSer.readFrom(msg, reader); + fininshed = MessageSerializer.readFrom(msgFactory, msg, reader); readPos = buf.position(); } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/SerializableDataBagItemWrapper.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/SerializableDataBagItemWrapper.java index 7e3bc16ed43e1..1ca007e1f7c56 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/SerializableDataBagItemWrapper.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/SerializableDataBagItemWrapper.java @@ -19,13 +19,13 @@ import java.io.Serializable; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; @@ -76,13 +76,13 @@ private T unwrap() { } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { if (data != null) dataBytes = U.marshal(marsh, data); } /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (dataBytes != null) { try { data = U.unmarshal(marsh, dataBytes, clsLdr); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java index b8fc471493069..4cd1def04c961 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryIoSession.java @@ -32,6 +32,7 @@ import javax.net.ssl.SSLSocket; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; +import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.direct.DirectMessageReader; import org.apache.ignite.internal.direct.DirectMessageWriter; import org.apache.ignite.internal.managers.communication.UnknownMessageException; @@ -39,6 +40,7 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.jdk.JdkMarshaller; import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage; import org.jetbrains.annotations.NotNull; @@ -145,7 +147,7 @@ void writeMessage(TcpDiscoveryAbstractMessage msg) throws IgniteCheckedException * @return Deserialized message instance. * @throws IgniteCheckedException If deserialization fails. */ - T readMessage() throws IgniteCheckedException, IOException { + T readMessage() throws IgniteCheckedException, IOException { try { byte b0 = (byte)in.read(); byte b1 = (byte)in.read(); @@ -167,8 +169,6 @@ T readMessage() throws IgniteCheckedException, IOException { msgReader.reset(); msgReader.setBuffer(msgBuf); - MessageSerializer msgSer = spi.messageFactory().serializer(msg.directType()); - boolean finished; do { @@ -181,7 +181,7 @@ T readMessage() throws IgniteCheckedException, IOException { msgBuf.limit(read); - finished = msgSer.readFrom(msg, msgReader); + finished = MessageSerializer.readFrom(spi.messageFactory(), msg, msgReader); // Server Discovery only sends next message to next Server upon receiving a receipt for the previous one. // This behaviour guarantees that we never read a next message from the buffer right after the end of @@ -197,6 +197,8 @@ T readMessage() throws IgniteCheckedException, IOException { } while (!finished); + MessageMarshaller.unmarshal(spi.messageFactory(), msg, ((IgniteEx)spi.ignite()).context()); + return (T)msg; } catch (Exception e) { @@ -238,8 +240,8 @@ public Socket socket() { * @param out Output stream to write serialized message. * @throws IOException If serialization fails. */ - void serializeMessage(Message m, OutputStream out) throws IOException { - MessageSerializer msgSer = spi.messageFactory().serializer(m.directType()); + void serializeMessage(Message m, OutputStream out) throws IOException, IgniteCheckedException { + MessageMarshaller.marshal(spi.messageFactory(), m, ((IgniteEx)spi.ignite()).context(), null); msgWriter.reset(); msgWriter.setBuffer(msgBuf); @@ -250,7 +252,7 @@ void serializeMessage(Message m, OutputStream out) throws IOException { // Should be cleared before first operation. msgBuf.clear(); - finished = msgSer.writeTo(m, msgWriter); + finished = MessageSerializer.writeTo(spi.messageFactory(), m, msgWriter); out.write(msgBuf.array(), 0, msgBuf.position()); } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java index eb868103ad1c2..c85ba9f010ee5 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java @@ -72,6 +72,7 @@ import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.resources.IgniteInstanceResource; import org.apache.ignite.resources.LoggerResource; @@ -1809,7 +1810,7 @@ protected void writeToSocket( * @throws IOException If IO failed or read timed out. * @throws IgniteCheckedException If unmarshalling failed. */ - protected T readMessage(TcpDiscoveryIoSession ses, long timeout) throws IOException, IgniteCheckedException { + protected T readMessage(TcpDiscoveryIoSession ses, long timeout) throws IOException, IgniteCheckedException { Socket sock = ses.socket(); assert sock != null; @@ -1819,7 +1820,9 @@ protected T readMessage(TcpDiscoveryIoSession ses, long timeout) throws IOEx try { sock.setSoTimeout((int)timeout); - return ses.readMessage(); + T msg = ses.readMessage(); + + return msg; } catch (IOException | IgniteCheckedException e) { if (X.hasCause(e, SocketTimeoutException.class)) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java index 2cfc4781230b8..a3bf5a7220c15 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java @@ -36,7 +36,7 @@ import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.ClusterMetricsSnapshot; import org.apache.ignite.internal.IgniteNodeAttributes; -import org.apache.ignite.internal.MarshallableMessage; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.managers.discovery.IgniteClusterNode; import org.apache.ignite.internal.processors.cluster.NodeMetricsMessage; @@ -49,6 +49,7 @@ import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.apache.ignite.spi.discovery.DiscoveryMetricsProvider; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; import org.jetbrains.annotations.Nullable; @@ -73,7 +74,8 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite /** Consistent ID. */ @GridToStringInclude - private Object consistentId; + @Marshalled("consistentIdBytes") + Object consistentId; /** Serialized {@link #consistentId}. */ @Order(1) @@ -81,7 +83,8 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Ignite /** Node attributes. */ @GridToStringExclude - private Map attrs; + @Marshalled("attrsBytes") + Map attrs; /** Serialized {@link #attrs}. */ @Order(2) @@ -220,29 +223,15 @@ public TcpDiscoveryNode(UUID id, } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (attrs != null) - attrsBytes = U.marshal(marsh, attrs); - - if (consistentId != null) - consistentIdBytes = U.marshal(marsh, consistentId); - + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { metricsMsg = new NodeMetricsMessage(metrics); } /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - if (attrsBytes != null) - attrs = U.unmarshal(marsh, attrsBytes, clsLdr); - - if (consistentIdBytes != null) - consistentId = U.unmarshal(marsh, consistentIdBytes, clsLdr); - + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (metricsMsg != null) metrics = new ClusterMetricsSnapshot(metricsMsg); - attrsBytes = null; - consistentIdBytes = null; metricsMsg = null; } @@ -311,6 +300,10 @@ public void lastSuccessfulAddress(InetSocketAddress lastSuccessfulAddr) { */ public void setAttributes(Map attrs) { this.attrs = U.sealMap(attrs); + + // Invalidate the @Marshalled cache: attrs are mutated after the first marshal (auth adds the security + // subject on join), and a stale attrsBytes would propagate the pre-auth attributes. + attrsBytes = null; } /** diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java index c36601a399567..75db3d55485f3 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java @@ -19,11 +19,11 @@ import java.util.UUID; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.jetbrains.annotations.Nullable; @@ -83,12 +83,12 @@ public Object readResolve() { } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { spanContainerBytes = spanContainer == null ? null : spanContainer.serializedSpanBytes(); } /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { if (spanContainerBytes != null) spanContainer.serializedSpanBytes(spanContainerBytes); } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java index ff6b252c439e0..4d68ba5b492e7 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryNodeAddFinishedMessage.java @@ -19,12 +19,10 @@ import java.util.Map; import java.util.UUID; -import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.Marshalled; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.spi.discovery.tcp.internal.DiscoveryDataPacket; import org.jetbrains.annotations.Nullable; @@ -47,7 +45,8 @@ public class TcpDiscoveryNodeAddFinishedMessage extends TcpDiscoveryAbstractTrac /** */ @GridToStringExclude - private Map clientNodeAttrs; + @Marshalled("clientNodeAttrsBytes") + Map clientNodeAttrs; /** Serialized client node attributes. */ @Order(2) @@ -122,20 +121,6 @@ public void clientNodeAttributes(Map clientNodeAttrs) { clientNodeAttrsBytes = null; } - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (clientNodeAttrs != null) - clientNodeAttrsBytes = U.marshal(marsh, clientNodeAttrs); - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - if (clientNodeAttrsBytes != null) - clientNodeAttrs = U.unmarshal(marsh, clientNodeAttrsBytes, clsLdr); - - clientNodeAttrsBytes = null; - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(TcpDiscoveryNodeAddFinishedMessage.class, this, "super", super.toString()); diff --git a/modules/core/src/test/java/org/apache/ignite/cdc/CdcCacheVersionTest.java b/modules/core/src/test/java/org/apache/ignite/cdc/CdcCacheVersionTest.java index aa33d3859b330..1d42ed57ece25 100644 --- a/modules/core/src/test/java/org/apache/ignite/cdc/CdcCacheVersionTest.java +++ b/modules/core/src/test/java/org/apache/ignite/cdc/CdcCacheVersionTest.java @@ -416,7 +416,7 @@ private void addConflictData( KeyCacheObject key = new KeyCacheObjectImpl(i, null, intCache.affinity().partition(i)); CacheObject val = new CacheObjectImpl(createUser(i), null); - val.prepareMarshal(intCache.context().cacheObjectContext()); + val.marshal(intCache.context().cacheObjectContext()); drMap.put(key, new GridCacheDrInfo(val, new GridCacheVersion(1, i, 1, OTHER_CLUSTER_ID))); } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/GridAffinityNoCacheSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/GridAffinityNoCacheSelfTest.java index 5d914886a46dc..cff11ed735ec3 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/GridAffinityNoCacheSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/GridAffinityNoCacheSelfTest.java @@ -284,13 +284,13 @@ private TestCacheObject(Object val) { } /** {@inheritDoc} */ - @Override public void finishUnmarshal(CacheObjectValueContext ctx, ClassLoader ldr) + @Override public void unmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { throw new UnsupportedOperationException(); } /** {@inheritDoc} */ - @Override public void prepareMarshal(CacheObjectValueContext ctx) throws IgniteCheckedException { + @Override public void marshal(CacheObjectValueContext ctx) throws IgniteCheckedException { throw new UnsupportedOperationException(); } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/codegen/MarshallerCacheFreeUnmarshalTest.java b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MarshallerCacheFreeUnmarshalTest.java new file mode 100644 index 0000000000000..99d6073aa9dfc --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MarshallerCacheFreeUnmarshalTest.java @@ -0,0 +1,110 @@ +/* + * 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.codegen; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import com.tngtech.archunit.base.DescribedPredicate; +import com.tngtech.archunit.core.domain.JavaClass; +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.core.domain.JavaCodeUnit; +import com.tngtech.archunit.core.domain.JavaMethodCall; +import com.tngtech.archunit.core.importer.ClassFileImporter; +import com.tngtech.archunit.core.importer.ImportOption; +import com.tngtech.archunit.lang.ArchRule; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; +import org.junit.BeforeClass; +import org.junit.Test; + +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; + +/** + * A message is finish-unmarshalled in two passes — cache-free (via {@code GridIoManager}) and cache-aware (via a + * subsystem) — and the mode-aware no-double-unmarshal check ({@link MessageMarshaller.Dedup}) deliberately allows + * both. So whatever the cache-free pass does must stay correct when the cache-aware pass runs it again. + * + *

The distinction is the side effect. A plain {@code @Marshalled} field unmarshals by assignment + * ({@code msg.x = ...}); assigning the same value twice is a no-op, so it is idempotent and needs no guarding. A + * {@code @MarshalledCollection} / {@code @MarshalledMap} field unmarshals by mutation ({@code collection.add} / + * {@code map.put}); running that twice appends the elements twice — a doubled, corrupt collection. So a collection/map + * mutation is the one thing that must not run in both passes, and the generator keeps it in the cache-aware pass only. + * + *

That is exactly what this rule checks — purely the mutating side effect, not the fields: the cache-free + * {@code unmarshal(msg, kctx)} overload of every generated marshaller must not call {@link Collection#add} or + * {@link Map#put}. Assignments are left unchecked (they can't break); a generator regression that moved an append into + * the cache-free pass — a real double-add the runtime check can't see, since it allows both passes — fails here. + */ +public class MarshallerCacheFreeUnmarshalTest { + /** + * The two-arg, cache-free {@code unmarshal} overload. The cache-aware overload takes a cache context and a + * class loader (four args); {@code unmarshalNio} shares the two-arg shape, so the name is matched too. + */ + private static final DescribedPredicate CACHE_FREE_UNMARSHAL = + new DescribedPredicate<>("cache-free unmarshal(msg, kctx)") { + @Override public boolean test(JavaCodeUnit unit) { + List params = unit.getRawParameterTypes(); + + return "unmarshal".equals(unit.getName()) + && params.size() == 2 + && params.get(1).isEquivalentTo(GridKernalContext.class); + } + }; + + /** A {@link Collection#add} or {@link Map#put} append made from within the cache-free {@code unmarshal}. */ + private static final DescribedPredicate CACHE_FREE_UNMARSHAL_APPEND = + new DescribedPredicate<>("Collection.add / Map.put from the cache-free unmarshal pass") { + @Override public boolean test(JavaMethodCall call) { + if (!CACHE_FREE_UNMARSHAL.test(call.getOrigin())) + return false; + + JavaClass owner = call.getTarget().getOwner(); + String mtd = call.getTarget().getName(); + + return owner.isAssignableTo(Collection.class) && "add".equals(mtd) + || owner.isAssignableTo(Map.class) && "put".equals(mtd); + } + }; + + /** All production classes on the classpath (the generated marshallers among them), excluding JARs. */ + private static JavaClasses classes; + + /** */ + @BeforeClass + public static void importClasses() { + classes = new ClassFileImporter() + .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_JARS) + .importPackages("org.apache.ignite"); + } + + /** The cache-free {@code unmarshal} overload must not append to collections/maps; those are cache-pass only. */ + @Test + public void cacheFreeFinishDoesNotAppendToCollections() { + ArchRule rule = noClasses() + .that() + .areAssignableTo(MessageMarshaller.class) + .should() + .callMethodWhere(CACHE_FREE_UNMARSHAL_APPEND) + .because("@MarshalledCollection/@MarshalledMap appends are non-idempotent and run only in the cache-aware " + + "unmarshal pass; an append in the cache-free pass would double-add when both passes run, which " + + "the mode-aware unmarshal-once check (MessageMarshaller.Dedup) permits and cannot catch."); + + rule.check(classes); + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java index e1e2e38dbbf5c..42491d1e0c043 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageProcessorTest.java @@ -35,6 +35,7 @@ import org.apache.ignite.internal.MessageProcessor; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.cache.query.QueryIndexMessage; +import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; import org.apache.ignite.internal.util.CommonUtils; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.lang.IgniteUuid; @@ -49,6 +50,24 @@ /** */ public class MessageProcessorTest { + /** */ + @Test + public void testMarshalledObjectsMessage() { + Compilation compilation = compile("TestMarshalledObjectsMessage.java"); + + assertThat(compilation).succeeded(); + + assertEquals(2, compilation.generatedSourceFiles().size()); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMarshalledObjectsMessageSerializer") + .hasSourceEquivalentTo(javaFile("TestMarshalledObjectsMessageSerializer.java")); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMarshalledObjectsMessageMarshaller") + .hasSourceEquivalentTo(javaFile("TestMarshalledObjectsMessageMarshaller.java")); + } + /** */ @Test public void testProcessorGeneratesSerializer() { @@ -56,11 +75,15 @@ public void testProcessorGeneratesSerializer() { assertThat(compilation).succeeded(); - assertEquals(1, compilation.generatedSourceFiles().size()); + assertEquals(2, compilation.generatedSourceFiles().size()); assertThat(compilation) .generatedSourceFile("org.apache.ignite.internal.TestMessageSerializer") .hasSourceEquivalentTo(javaFile("TestMessageSerializer.java")); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMessageMarshaller") + .hasSourceEquivalentTo(javaFile("TestMessageMarshaller.java")); } /** */ @@ -70,11 +93,15 @@ public void testCollectionsMessage() { assertThat(compilation).succeeded(); - assertEquals(1, compilation.generatedSourceFiles().size()); + assertEquals(2, compilation.generatedSourceFiles().size()); assertThat(compilation) .generatedSourceFile("org.apache.ignite.internal.TestCollectionsMessageSerializer") .hasSourceEquivalentTo(javaFile("TestCollectionsMessageSerializer.java")); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestCollectionsMessageMarshaller") + .hasSourceEquivalentTo(javaFile("TestCollectionsMessageMarshaller.java")); } /** */ @@ -84,11 +111,15 @@ public void testMapMessage() { assertThat(compilation).succeeded(); - assertEquals(1, compilation.generatedSourceFiles().size()); + assertEquals(2, compilation.generatedSourceFiles().size()); assertThat(compilation) .generatedSourceFile("org.apache.ignite.internal.TestMapMessageSerializer") .hasSourceEquivalentTo(javaFile("TestMapMessageSerializer.java")); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMapMessageMarshaller") + .hasSourceEquivalentTo(javaFile("TestMapMessageMarshaller.java")); } /** */ @@ -131,11 +162,15 @@ public void testInheritedMessages() { assertThat(compilation).succeeded(); - assertEquals(1, compilation.generatedSourceFiles().size()); + assertEquals(2, compilation.generatedSourceFiles().size()); assertThat(compilation) .generatedSourceFile("org.apache.ignite.internal.ChildMessageSerializer") .hasSourceEquivalentTo(javaFile("ChildMessageSerializer.java")); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.ChildMessageMarshaller") + .hasSourceEquivalentTo(javaFile("ChildMessageMarshaller.java")); } /** */ @@ -145,15 +180,23 @@ public void testMultipleMessages() { assertThat(compilation).succeeded(); - assertEquals(2, compilation.generatedSourceFiles().size()); + assertEquals(4, compilation.generatedSourceFiles().size()); assertThat(compilation) .generatedSourceFile("org.apache.ignite.internal.ChildMessageSerializer") .hasSourceEquivalentTo(javaFile("ChildMessageSerializer.java")); + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.ChildMessageMarshaller") + .hasSourceEquivalentTo(javaFile("ChildMessageMarshaller.java")); + assertThat(compilation) .generatedSourceFile("org.apache.ignite.internal.TestMessageSerializer") .hasSourceEquivalentTo(javaFile("TestMessageSerializer.java")); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMessageMarshaller") + .hasSourceEquivalentTo(javaFile("TestMessageMarshaller.java")); } /** */ @@ -218,9 +261,15 @@ public void testDefaultMapperEnumFields() { assertThat(compilation).succeeded(); + assertEquals(2, compilation.generatedSourceFiles().size()); + assertThat(compilation) .generatedSourceFile("org.apache.ignite.internal.DefaultMapperEnumFieldsMessageSerializer") .hasSourceEquivalentTo(javaFile("DefaultMapperEnumFieldsMessageSerializer.java")); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.DefaultMapperEnumFieldsMessageMarshaller") + .hasSourceEquivalentTo(javaFile("DefaultMapperEnumFieldsMessageMarshaller.java")); } /** @@ -258,9 +307,15 @@ public void testCustomMapperEnumFieldsMessage() { assertThat(compilation).succeeded(); + assertEquals(2, compilation.generatedSourceFiles().size()); + assertThat(compilation) .generatedSourceFile("org.apache.ignite.internal.CustomMapperEnumFieldsMessageSerializer") .hasSourceEquivalentTo(javaFile("CustomMapperEnumFieldsMessageSerializer.java")); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.CustomMapperEnumFieldsMessageMarshaller") + .hasSourceEquivalentTo(javaFile("CustomMapperEnumFieldsMessageMarshaller.java")); } /** */ @@ -270,9 +325,15 @@ public void testMarshallableMessage() { assertThat(compilation).succeeded(); + assertEquals(2, compilation.generatedSourceFiles().size()); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMarshallableMessageSerializer") + .hasSourceEquivalentTo(javaFile("TestMarshallableMessageSerializer.java")); + assertThat(compilation) - .generatedSourceFile("org.apache.ignite.internal.TestMarshallableMessageMarshallableSerializer") - .hasSourceEquivalentTo(javaFile("TestMarshallableMessageMarshallableSerializer.java")); + .generatedSourceFile("org.apache.ignite.internal.TestMarshallableMessageMarshaller") + .hasSourceEquivalentTo(javaFile("TestMarshallableMessageMarshaller.java")); } /** @@ -351,6 +412,116 @@ public void testCompressAnnotationFailsForUnsupportedTypes() { assertThat(compilation).hadErrorContaining("Compress annotation is used for an unsupported type: java.util.List"); } + /** Verifies that {@code @NioField} on a non-{@link Message}-typed field is a compilation error. */ + @Test + public void testNioFieldOnNonMessageTypeFails() { + Compilation compilation = compile("NioFieldOnNonMessageMessage.java"); + + assertThat(compilation).failed(); + assertThat(compilation).hadErrorContaining("@NioField has no effect on non-Message field"); + } + + /** Verifies that {@code @Marshalled} generates {@code U.unmarshal} with a blank line before the null-out. */ + @Test + public void testMarshalledMessage() { + Compilation compilation = compile("TestMarshalledMessage.java"); + + assertThat(compilation).succeeded(); + + assertEquals(2, compilation.generatedSourceFiles().size()); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMarshalledMessageSerializer") + .hasSourceEquivalentTo(javaFile("TestMarshalledMessageSerializer.java")); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMarshalledMessageMarshaller") + .hasSourceEquivalentTo(javaFile("TestMarshalledMessageMarshaller.java")); + } + + /** Verifies that {@code @MarshalledCollection} generates Set reconstruction in FINISH_CACHE mode. */ + @Test + public void testMarshalledCollectionMessage() { + Compilation compilation = compile("TestMarshalledCollectionMessage.java"); + + assertThat(compilation).succeeded(); + + assertEquals(2, compilation.generatedSourceFiles().size()); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMarshalledCollectionMessageSerializer") + .hasSourceEquivalentTo(javaFile("TestMarshalledCollectionMessageSerializer.java")); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMarshalledCollectionMessageMarshaller") + .hasSourceEquivalentTo(javaFile("TestMarshalledCollectionMessageMarshaller.java")); + } + + /** Verifies that {@code @MarshalledMap} generates Map reconstruction in FINISH_CACHE mode. */ + @Test + public void testMarshalledMapMessage() { + Compilation compilation = compile("TestMarshalledMapMessage.java"); + + assertThat(compilation).succeeded(); + + assertEquals(2, compilation.generatedSourceFiles().size()); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMarshalledMapMessageSerializer") + .hasSourceEquivalentTo(javaFile("TestMarshalledMapMessageSerializer.java")); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestMarshalledMapMessageMarshaller") + .hasSourceEquivalentTo(javaFile("TestMarshalledMapMessageMarshaller.java")); + } + + /** Verifies a deployable {@link GridCacheIdMessage} gets a generated deployer that bridges cache-object fields. */ + @Test + public void testDeployerGeneration() { + Compilation compilation = compile("TestCacheIdMessage.java"); + + assertThat(compilation).succeeded(); + + assertEquals(3, compilation.generatedSourceFiles().size()); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestCacheIdMessageDeployer") + .hasSourceEquivalentTo(javaFile("TestCacheIdMessageDeployer.java")); + } + + /** Verifies a {@code DeployableMessage}'s generated deployer delegates to its custom {@code deploy}. */ + @Test + public void testDeployerDelegatesToCustomDeployment() { + Compilation compilation = compile("TestDeployableMessage.java"); + + assertThat(compilation).succeeded(); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestDeployableMessageDeployer") + .hasSourceEquivalentTo(javaFile("TestDeployableMessageDeployer.java")); + } + + /** Verifies a nested {@link GridCacheMessage} field is deployed by delegating to the static facade entry point. */ + @Test + public void testDeployerHandlesNestedMessage() { + Compilation compilation = compile("TestNestedDeployMessage.java", "TestCacheIdMessage.java"); + + assertThat(compilation).succeeded(); + + assertThat(compilation) + .generatedSourceFile("org.apache.ignite.internal.TestNestedDeployMessageDeployer") + .hasSourceEquivalentTo(javaFile("TestNestedDeployMessageDeployer.java")); + } + + /** Verifies the generator fails fast when a deployable message cannot resolve a cache context. */ + @Test + public void testDeployerFailsWithoutCacheContext() { + Compilation compilation = compile("TestNoCacheCtxMessage.java"); + + assertThat(compilation).failed(); + assertThat(compilation).hadErrorContaining("Cannot resolve cache context"); + } + /** */ private Compilation compile(String... srcFiles) { return compile(new MessageProcessor(), srcFiles); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageSerializationArchitectureTest.java b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageSerializationArchitectureTest.java new file mode 100644 index 0000000000000..ae75825969587 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/codegen/MessageSerializationArchitectureTest.java @@ -0,0 +1,154 @@ +/* + * 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.codegen; + +import com.tngtech.archunit.base.DescribedPredicate; +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.core.domain.JavaMethodCall; +import com.tngtech.archunit.core.domain.JavaModifier; +import com.tngtech.archunit.core.domain.properties.HasOwner; +import com.tngtech.archunit.core.importer.ClassFileImporter; +import com.tngtech.archunit.core.importer.ImportOption; +import com.tngtech.archunit.lang.ArchRule; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.junit.BeforeClass; +import org.junit.Test; + +import static com.tngtech.archunit.core.domain.JavaCall.Predicates.target; +import static com.tngtech.archunit.core.domain.JavaClass.Predicates.assignableTo; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; + +/** + * Verifies that instance methods of {@link MessageSerializer}, {@link MessageMarshaller} and + * {@link GridCacheMessageDeployer} are only called from classes that implement these interfaces (i.e. generated + * serializers/marshallers/deployers and their hand-written wrappers). All other code must use the static + * convenience methods: + *

    + *
  • {@link MessageSerializer#writeTo(org.apache.ignite.plugin.extensions.communication.MessageFactory, + * org.apache.ignite.plugin.extensions.communication.Message, + * org.apache.ignite.plugin.extensions.communication.MessageWriter)}
  • + *
  • {@link MessageSerializer#readFrom(org.apache.ignite.plugin.extensions.communication.MessageFactory, + * org.apache.ignite.plugin.extensions.communication.Message, + * org.apache.ignite.plugin.extensions.communication.MessageReader)}
  • + *
  • {@link MessageMarshaller#marshal}
  • + *
  • {@link MessageMarshaller#unmarshal}
  • + *
  • static {@code GridCacheMessageDeployer.deploy(factory, msg, ctx)}
  • + *
+ * + *

The rules key on whether the called method is {@code static}, not on its name — so any instance method added + * to these interfaces is covered automatically. + */ +public class MessageSerializationArchitectureTest { + /** Matches method calls that resolve to a non-static (instance) method. */ + private static final DescribedPredicate TO_INSTANCE_METHOD = + new DescribedPredicate<>("to instance method") { + @Override public boolean test(JavaMethodCall call) { + return call.getTarget().resolveMember() + .map(m -> !m.getModifiers().contains(JavaModifier.STATIC)) + .orElse(false); + } + }; + + /** Classes under analysis: all production + test sources on the classpath, excluding JARs. */ + private static JavaClasses classes; + + /** */ + @BeforeClass + public static void importClasses() { + classes = new ClassFileImporter() + .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_JARS) + .importPackages("org.apache.ignite"); + } + + /** + * Instance methods of {@link MessageSerializer} ({@code writeTo}, {@code readFrom}) must only be + * called from within classes that themselves implement {@link MessageSerializer} — i.e. generated + * serializers and hand-written wrappers that delegate to the underlying serializer. + * + * Everyone else must use + * {@link MessageSerializer#writeTo(org.apache.ignite.plugin.extensions.communication.MessageFactory, + * org.apache.ignite.plugin.extensions.communication.Message, + * org.apache.ignite.plugin.extensions.communication.MessageWriter)} and + * {@link MessageSerializer#readFrom(org.apache.ignite.plugin.extensions.communication.MessageFactory, + * org.apache.ignite.plugin.extensions.communication.Message, + * org.apache.ignite.plugin.extensions.communication.MessageReader)}. + */ + @Test + public void serializerInstanceMethodsOnlyCalledFromImplementations() { + ArchRule rule = noClasses() + .that() + // Exclude MessageSerializer itself and all its implementations (generated + wrappers). + .areNotAssignableTo(MessageSerializer.class) + .should() + .callMethodWhere(TO_INSTANCE_METHOD + .and(target(HasOwner.Predicates.With.owner(assignableTo(MessageSerializer.class)))) + ) + .because("Use static MessageSerializer.writeTo(factory, msg, writer) and " + + "MessageSerializer.readFrom(factory, msg, reader) instead of calling instance methods directly."); + + rule.check(classes); + } + + /** + * Instance methods of {@link MessageMarshaller} ({@code marshal}, {@code unmarshal}) must + * only be called from within classes that themselves implement {@link MessageMarshaller} — i.e. generated + * marshallers and hand-written wrappers that delegate to the underlying marshaller. + * + * Everyone else must use the static + * {@link MessageMarshaller#marshal} and {@link MessageMarshaller#unmarshal} methods. + */ + @Test + public void marshallerInstanceMethodsOnlyCalledFromImplementations() { + ArchRule rule = noClasses() + .that() + // Exclude MessageMarshaller itself and all its implementations (generated + wrappers). + .areNotAssignableTo(MessageMarshaller.class) + .should() + .callMethodWhere(TO_INSTANCE_METHOD + .and(target(HasOwner.Predicates.With.owner(assignableTo(MessageMarshaller.class)))) + ) + .because("Use static MessageMarshaller.marshal(factory, ...) and " + + "MessageMarshaller.unmarshal(factory, ...) instead of calling instance methods directly."); + + rule.check(classes); + } + + /** + * Instance method of {@link GridCacheMessageDeployer} ({@code deploy}) must only be called from + * within classes that themselves implement {@link GridCacheMessageDeployer} — i.e. generated deployers. + * + * Everyone else must use the static {@code GridCacheMessageDeployer.deploy(factory, msg, ctx)} facade. + */ + @Test + public void deployerInstanceMethodOnlyCalledFromImplementations() { + ArchRule rule = noClasses() + .that() + // Exclude GridCacheMessageDeployer itself and all its implementations (generated deployers). + .areNotAssignableTo(GridCacheMessageDeployer.class) + .should() + .callMethodWhere(TO_INSTANCE_METHOD + .and(target(HasOwner.Predicates.With.owner(assignableTo(GridCacheMessageDeployer.class)))) + ) + .because("Use static GridCacheMessageDeployer.deploy(factory, msg, ctx) instead of " + + "calling the instance method directly."); + + rule.check(classes); + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStreamImplByteOrderSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStreamImplByteOrderSelfTest.java index 4c5a786c7e862..44e2b7cfb2fdf 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStreamImplByteOrderSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStreamImplByteOrderSelfTest.java @@ -25,10 +25,12 @@ import java.util.function.Supplier; import org.apache.commons.lang3.StringUtils; import org.apache.ignite.IgniteException; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; import org.apache.ignite.internal.util.GridUnsafe; import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.jetbrains.annotations.Nullable; import org.junit.Before; @@ -87,12 +89,8 @@ public void setUp() throws Exception { */ private static DirectByteBufferStream createStream(ByteBuffer buff) { DirectByteBufferStream stream = new DirectByteBufferStream(new MessageFactory() { - @Override public void register(short directType, Supplier supplier) throws IgniteException { - throw new UnsupportedOperationException(); - } - - @Override public void register(short directType, Supplier supplier, - MessageSerializer serializer) throws IgniteException { + @Override public void register(short directType, Supplier supplier, MessageSerializer serializer, + @Nullable MessageMarshaller marshaller, @Nullable GridCacheMessageDeployer deployer) throws IgniteException { throw new UnsupportedOperationException(); } @@ -103,6 +101,10 @@ private static DirectByteBufferStream createStream(ByteBuffer buff) { @Override public MessageSerializer serializer(short type) { return null; } + + @Nullable @Override public MessageMarshaller marshaller(short type) { + return null; + } }); stream.setBuffer(buff); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/managers/AbstractMessageSerializationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/managers/AbstractMessageSerializationTest.java index 82d3d96ba0f16..5ffa58606d71d 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/managers/AbstractMessageSerializationTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/managers/AbstractMessageSerializationTest.java @@ -39,6 +39,7 @@ import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; import org.apache.ignite.plugin.extensions.communication.MessageMapType; import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.plugin.extensions.communication.MessageWriter; import org.apache.ignite.spi.communication.tcp.messages.HandshakeMessage; import org.jetbrains.annotations.Nullable; @@ -103,13 +104,13 @@ private void checkSerializationAndDeserializationConsistency( initializeMessage(msg); - while (!msgFactory.serializer(msgType).writeTo(msg, writer)) { + while (!MessageSerializer.writeTo(msgFactory, msg, writer)) { // No-op. } msg = msgFactory.create(msgType); - while (!msgFactory.serializer(msgType).readFrom(msg, reader)) { + while (!MessageSerializer.readFrom(msgFactory, msg, reader)) { // No-op. } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/managers/communication/ErrorMessageSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/managers/communication/ErrorMessageSelfTest.java index b3ff36de94b8a..72ed44eacb6a2 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/managers/communication/ErrorMessageSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/managers/communication/ErrorMessageSelfTest.java @@ -40,7 +40,7 @@ public void testDirectAndInsverseConversion() throws IgniteCheckedException { assertSame(e, msg0.error()); - msg0.prepareMarshal(jdk()); + msg0.marshal(jdk()); byte[] errBytes = msg0.errBytes; @@ -49,7 +49,7 @@ public void testDirectAndInsverseConversion() throws IgniteCheckedException { ErrorMessage msg1 = new ErrorMessage(); msg1.errBytes = errBytes; - msg1.finishUnmarshal(jdk(), U.gridClassLoader()); + msg1.unmarshal(jdk(), U.gridClassLoader()); Throwable t = msg1.error(); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheMetricsCacheSizeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheMetricsCacheSizeTest.java index 77616ae9e8d2b..cb91e85a346f7 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheMetricsCacheSizeTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheMetricsCacheSizeTest.java @@ -106,8 +106,6 @@ public void testCacheSize() throws Exception { msg.addServerCacheMetrics(srvrId, cacheMetrics); MessageFactory msgFactory = ((TcpDiscoverySpi)grid(0).context().discovery().getInjectedDiscoverySpi()).messageFactory(); - MessageSerializer msgSerializer = msgFactory.serializer(msg.directType()); - // First time we write initial message type which is not read by the reader because the message type is known. // We have to skip this header at the further message reading. AtomicInteger initHdrSize = new AtomicInteger(); @@ -123,7 +121,7 @@ public void testCacheSize() throws Exception { // 2kb should be enough for an empty message even if it is a relatively large metrics message. msgWritter.setBuffer(ByteBuffer.allocate(2048)); - assertTrue(msgSerializer.writeTo(msg, msgWritter)); + assertTrue(MessageSerializer.writeTo(msgFactory, msg, msgWritter)); assertTrue(msgWritter.getBuffer().hasRemaining()); @@ -135,7 +133,7 @@ public void testCacheSize() throws Exception { TcpDiscoveryMetricsUpdateMessage msg2 = new TcpDiscoveryMetricsUpdateMessage(); - assertTrue(msgSerializer.readFrom(msg2, msgReader)); + assertTrue(MessageSerializer.readFrom(msgFactory, msg2, msgReader)); Map cacheMetrics2 = msg2.serversFullMetricsMessages().values().iterator().next() .cachesMetricsMessages(); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryAbstractTest.java index fd6c6f9e4befd..4cb06c7fb441a 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryAbstractTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/ClientSlowDiscoveryAbstractTest.java @@ -93,7 +93,7 @@ static class CustomMessageInterceptingDiscoverySpi extends TcpDiscoverySpi { TcpDiscoveryCustomEventMessage cm = (TcpDiscoveryCustomEventMessage)msg; try { - cm.finishUnmarshal(marshaller(), U.resolveClassLoader(ignite().configuration())); + cm.unmarshal(marshaller(), U.resolveClassLoader(ignite().configuration())); assertNotNull(cm.message()); } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheIoManagerRetryTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheIoManagerRetryTest.java index 0ab5cd5382219..39d54e07d8831 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheIoManagerRetryTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheIoManagerRetryTest.java @@ -27,6 +27,7 @@ import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.GridTopic; +import org.apache.ignite.internal.IgniteKernal; import org.apache.ignite.internal.managers.communication.GridIoManager; import org.apache.ignite.internal.managers.deployment.GridDeploymentManager; import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; @@ -128,6 +129,8 @@ private void doTest(Function action) throws Except cacheIoMgr.start(cctx); + ((IgniteKernal)cacheIoMgr.context().kernalContext().grid()).initMessageFactory(); + return cacheIoMgr; } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteIncompleteCacheObjectSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteIncompleteCacheObjectSelfTest.java index 0e8f4676f0c73..f280524648a01 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteIncompleteCacheObjectSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteIncompleteCacheObjectSelfTest.java @@ -149,13 +149,13 @@ private TestCacheObject(final byte type) { } /** {@inheritDoc} */ - @Override public void finishUnmarshal(final CacheObjectValueContext ctx, final ClassLoader ldr) + @Override public void unmarshal(final CacheObjectValueContext ctx, final ClassLoader ldr) throws IgniteCheckedException { // No-op } /** {@inheritDoc} */ - @Override public void prepareMarshal(final CacheObjectValueContext ctx) throws IgniteCheckedException { + @Override public void marshal(final CacheObjectValueContext ctx) throws IgniteCheckedException { // No-op } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClientRequestsMappingTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClientRequestsMappingTest.java index fe4a0eeb70809..03cfabc9729d6 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClientRequestsMappingTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteMarshallerCacheClientRequestsMappingTest.java @@ -163,7 +163,7 @@ private void doTestMarshallingBinaryMappingsLoadedFromClient(boolean receiveMeta try { TcpDiscoveryCustomEventMessage evtMsg = (TcpDiscoveryCustomEventMessage)msg; - evtMsg.finishUnmarshal(marshaller(), U.gridClassLoader()); + evtMsg.unmarshal(marshaller(), U.gridClassLoader()); DiscoveryCustomMessage delegate = U.unwrapCustomMessage(evtMsg.message()); @@ -239,7 +239,7 @@ public void testBinaryMetaDelayedForComputeJobResult() throws Exception { try { TcpDiscoveryCustomEventMessage evtMsg = (TcpDiscoveryCustomEventMessage)msg; - evtMsg.finishUnmarshal(marshaller(), U.gridClassLoader()); + evtMsg.unmarshal(marshaller(), U.gridClassLoader()); DiscoveryCustomMessage delegate = U.unwrapCustomMessage(evtMsg.message()); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgniteSequentialNodeCrashRecoveryTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgniteSequentialNodeCrashRecoveryTest.java index e404873a8ccad..57139ce4c5bc5 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgniteSequentialNodeCrashRecoveryTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgniteSequentialNodeCrashRecoveryTest.java @@ -357,7 +357,7 @@ private DiscoveryCustomMessage extractCustomMessage(TcpDiscoveryCustomEventMessa DiscoveryCustomMessage msgObj = null; try { - msg.finishUnmarshal(marshaller(), U.gridClassLoader()); + msg.unmarshal(marshaller(), U.gridClassLoader()); msgObj = (DiscoveryCustomMessage)msg.message(); } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotTest.java index 6224135de075f..36bbaee3883a6 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotTest.java @@ -23,6 +23,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.UnaryOperator; import org.apache.ignite.IgniteCache; +import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.cache.QueryEntity; import org.apache.ignite.cluster.ClusterState; @@ -51,6 +52,7 @@ import static org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType.RESTORE_CACHE_GROUP_SNAPSHOT_PREPARE; import static org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType.RESTORE_CACHE_GROUP_SNAPSHOT_START; import static org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType.RESTORE_INCREMENTAL_SNAPSHOT_START; +import static org.apache.ignite.marshaller.Marshallers.jdk; import static org.apache.ignite.testframework.GridTestUtils.assertThrows; import static org.apache.ignite.testframework.GridTestUtils.assertThrowsWithCause; import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; @@ -426,8 +428,18 @@ public void testStagesFail() throws Exception { DistributedProcess.DistributedProcessType stage = failStage.get(); - if (stage != null && stage.ordinal() == singleMsg.type()) - GridTestUtils.setFieldValue(singleMsg, "errMsg", new ErrorMessage(new IgniteException("Test exception."))); + if (stage != null && stage.ordinal() == singleMsg.type()) { + ErrorMessage em = new ErrorMessage(new IgniteException("Test exception.")); + + try { + em.marshal(jdk()); + } + catch (IgniteCheckedException e) { + throw new RuntimeException(e); + } + + GridTestUtils.setFieldValue(singleMsg, "errMsg", em); + } } return false; diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java index 782b67148becc..d025cbb48f195 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java @@ -1031,7 +1031,7 @@ public void testDumpEntryConflictVersion() throws Exception { KeyCacheObject key = new KeyCacheObjectImpl(i, null, intCache.affinity().partition(i)); CacheObject val = new CacheObjectImpl(i, null); - val.prepareMarshal(intCache.context().cacheObjectContext()); + val.marshal(intCache.context().cacheObjectContext()); drMap.put(key, new GridCacheDrInfo(val, new GridCacheVersion(topVer, i, nodeOrder, dataCenterId))); } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotJoiningClientTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotJoiningClientTest.java index fd42dc16fbf41..3930051c86dcc 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotJoiningClientTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotJoiningClientTest.java @@ -246,7 +246,7 @@ private static class CoordinatorBlockingDiscoverySpi extends TcpDiscoverySpi { TcpDiscoveryCustomEventMessage m = (TcpDiscoveryCustomEventMessage)msg; try { - m.finishUnmarshal(marshaller(), U.resolveClassLoader(ignite().configuration())); + m.unmarshal(marshaller(), U.resolveClassLoader(ignite().configuration())); if (U.unwrapCustomMessage(m.message()) instanceof InitMessage) rcvStartSnpReq.countDown(); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryImmutableEntryTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryImmutableEntryTest.java index a41490c0e405f..141ed3a925cb3 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryImmutableEntryTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryImmutableEntryTest.java @@ -39,6 +39,7 @@ import org.apache.ignite.internal.processors.cache.KeyCacheObjectImpl; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.junit.Test; @@ -155,14 +156,13 @@ public void testCacheContinuousQueryEntrySerialization() { ByteBuffer buf = ByteBuffer.allocate(4096); DirectMessageWriter writer = new DirectMessageWriter(msgFactory); - var serializer = msgFactory.serializer(e0.directType()); - assertNotNull("Serializer not found for message type " + e0.directType(), serializer); + assertNotNull("Serializer not found for message type " + e0.directType(), msgFactory.serializer(e0.directType())); writer.setBuffer(buf); // Skip write class header. writer.onHeaderWritten(); - serializer.writeTo(e0, writer); + MessageSerializer.writeTo(msgFactory, e0, writer); CacheContinuousQueryEntry e1 = new CacheContinuousQueryEntry(); @@ -170,7 +170,7 @@ public void testCacheContinuousQueryEntrySerialization() { reader.setBuffer(ByteBuffer.wrap(buf.array())); - serializer.readFrom(e1, reader); + MessageSerializer.readFrom(msgFactory, e1, reader); assertEquals(e0.cacheId(), e1.cacheId()); assertEquals(e0.eventType(), e1.eventType()); @@ -182,11 +182,11 @@ public void testCacheContinuousQueryEntrySerialization() { // Key and value shouldn't be serialized in case an event is filtered. assertNull(e1.key()); - assertNotNull(e0.key()); + assertNull(e0.key()); assertNull(e1.oldValue()); - assertNotNull(e0.oldValue()); + assertNull(e0.oldValue()); assertNull(e1.newValue()); - assertNotNull(e0.newValue()); + assertNull(e0.newValue()); } /** @@ -207,7 +207,7 @@ private static class CacheEventFilter implements CacheEntryEventFilter evt) { evts.add(evt); - return false; + return true; } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxDeadlockDetectionMessageMarshallingTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxDeadlockDetectionMessageMarshallingTest.java index a6d6375c1ed87..fb5e18b568896 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxDeadlockDetectionMessageMarshallingTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxDeadlockDetectionMessageMarshallingTest.java @@ -28,9 +28,11 @@ import org.apache.ignite.internal.managers.communication.GridIoPolicy; import org.apache.ignite.internal.managers.communication.GridMessageListener; import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cache.IgniteCacheProxy; import org.apache.ignite.internal.processors.cache.KeyCacheObject; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.junit.Test; @@ -65,7 +67,8 @@ public void testMessageUnmarshallWithoutCacheContext() throws Exception { @Override public void onMessage(UUID nodeId, Object msg, byte plc) { if (msg instanceof TxLocksResponse) { try { - ((TxLocksResponse)msg).finishUnmarshal(clientCtx, clientCtx.deploy().globalLoader()); + MessageMarshaller.unmarshal(clientCtx.kernalContext().messageFactory(), (TxLocksResponse)msg, + clientCtx.kernalContext(), null, clientCtx.deploy().globalLoader()); res.set(true); } @@ -86,7 +89,7 @@ public void testMessageUnmarshallWithoutCacheContext() throws Exception { TxLocksResponse msg = new TxLocksResponse(); msg.addKey(cctx.txKey(key)); - msg.prepareMarshal(cctx.shared()); + GridCacheMessageDeployer.deploy(cctx.kernalContext().messageFactory(), msg, cctx.shared()); ((IgniteKernal)ignite).context().cache().context().gridIO().sendToCustomTopic( ((IgniteKernal)client).localNode(), TOPIC, msg, GridIoPolicy.PUBLIC_POOL); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/CacheFreeListSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/CacheFreeListSelfTest.java index 8817a3ba49ebc..3b317c5db3836 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/CacheFreeListSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/CacheFreeListSelfTest.java @@ -725,13 +725,13 @@ private TestCacheObject(int size) { } /** {@inheritDoc} */ - @Override public void finishUnmarshal(CacheObjectValueContext ctx, ClassLoader ldr) + @Override public void unmarshal(CacheObjectValueContext ctx, ClassLoader ldr) throws IgniteCheckedException { assert false; } /** {@inheritDoc} */ - @Override public void prepareMarshal(CacheObjectValueContext ctx) throws IgniteCheckedException { + @Override public void marshal(CacheObjectValueContext ctx) throws IgniteCheckedException { assert false; } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImplSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImplSelfTest.java index 625f290d1c6fc..6cb74d0483bf2 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImplSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImplSelfTest.java @@ -32,6 +32,7 @@ import javax.cache.CacheException; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; +import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteDataStreamer; import org.apache.ignite.IgniteException; import org.apache.ignite.IgniteLogger; @@ -51,6 +52,7 @@ import org.apache.ignite.lang.IgniteFuture; import org.apache.ignite.lang.IgniteInClosure; import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; import org.apache.ignite.stream.StreamReceiver; import org.apache.ignite.testframework.GridTestUtils; @@ -713,6 +715,14 @@ private static class StaleTopologyCommunicationSpi extends TcpCommunicationSpi { ioMsg.skipOnTimeout() ); + try { + MessageMarshaller.marshal(((IgniteEx)ignite).context().messageFactory(), + msg, ((IgniteEx)ignite).context(), null); + } + catch (IgniteCheckedException e) { + throw new RuntimeException(e); + } + needStaleTop = false; } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/query/schema/IndexWithSameNameTestBase.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/query/schema/IndexWithSameNameTestBase.java index e37cee61fc560..efaaae6793ba2 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/query/schema/IndexWithSameNameTestBase.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/query/schema/IndexWithSameNameTestBase.java @@ -313,7 +313,7 @@ public static class SchemaFinishListeningTcpDiscoverySpi extends TcpDiscoverySpi try { TcpDiscoveryCustomEventMessage evtMsg = (TcpDiscoveryCustomEventMessage)msg; - evtMsg.finishUnmarshal(marshaller(), U.gridClassLoader()); + evtMsg.unmarshal(marshaller(), U.gridClassLoader()); DiscoveryCustomMessage discoCustomMsg = U.unwrapCustomMessage(evtMsg.message()); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/util/nio/IgniteExceptionInNioWorkerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/util/nio/IgniteExceptionInNioWorkerSelfTest.java index bceb60e4f6375..ce3f9fbeca5f0 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/util/nio/IgniteExceptionInNioWorkerSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/util/nio/IgniteExceptionInNioWorkerSelfTest.java @@ -18,11 +18,19 @@ package org.apache.ignite.internal.util.nio; import java.util.UUID; +import org.apache.ignite.IgniteException; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.GridTopic; import org.apache.ignite.internal.IgniteDiagnosticRequest; import org.apache.ignite.internal.IgniteKernal; +import org.apache.ignite.plugin.AbstractTestPluginProvider; +import org.apache.ignite.plugin.ExtensionRegistry; +import org.apache.ignite.plugin.PluginContext; +import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.junit.Test; @@ -43,6 +51,8 @@ public class IgniteExceptionInNioWorkerSelfTest extends GridCommonAbstractTest { cfg.setCacheConfiguration(ccfg); + cfg.setPluginProviders(new BrokenMessageProvider()); + return cfg; } @@ -73,19 +83,50 @@ public void testBrokenMessage() throws Exception { * */ private static class BrokenMessage extends IgniteDiagnosticRequest { + // No-op. + } + + /** Serializer that throws on the first {@code writeTo} call to simulate a broken message. */ + private static class BrokenMessageSerializer implements MessageSerializer { /** */ private boolean fail = true; /** {@inheritDoc} */ - @Override public short directType() { + @Override public boolean writeTo(BrokenMessage msg, MessageWriter writer) { + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(msg.directType())) + return false; + + writer.onHeaderWritten(); + } + if (fail) { fail = false; - return (byte)242; + throw new IgniteException("Broken message"); } - // IgniteDiagnosticRequest as an example. - return 13003; + return true; + } + + /** {@inheritDoc} */ + @Override public boolean readFrom(BrokenMessage msg, MessageReader reader) { + return true; + } + } + + /** Plugin provider that registers {@link BrokenMessageSerializer} for {@link BrokenMessage}. */ + public static class BrokenMessageProvider extends AbstractTestPluginProvider { + /** {@inheritDoc} */ + @Override public String name() { + return getClass().getName(); + } + + /** {@inheritDoc} */ + @Override public void initExtensions(PluginContext ctx, ExtensionRegistry registry) { + registry.registerExtension(MessageFactoryProvider.class, (factory) -> + factory.register(-42, BrokenMessage::new, new BrokenMessageSerializer()) + ); } } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/util/nio/TcpCommunicationSpiSslVolatilePayloadTest.java b/modules/core/src/test/java/org/apache/ignite/internal/util/nio/TcpCommunicationSpiSslVolatilePayloadTest.java index 9be2ee3156092..45c0d0ea029d6 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/util/nio/TcpCommunicationSpiSslVolatilePayloadTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/util/nio/TcpCommunicationSpiSslVolatilePayloadTest.java @@ -96,7 +96,8 @@ public class TcpCommunicationSpiSslVolatilePayloadTest extends GridAbstractCommu /** {@inheritDoc} */ @Override protected MessageFactoryProvider customMessageFactory() { return f -> f.register( - TestVolatilePayloadMessage.DIRECT_TYPE, TestVolatilePayloadMessage::new, new TestVolatilePayloadMessageSerializer() + TestVolatilePayloadMessage.DIRECT_TYPE, + TestVolatilePayloadMessage::new, new TestVolatilePayloadMessageSerializer() ); } diff --git a/modules/core/src/test/java/org/apache/ignite/p2p/ClassLoadingProblemExceptionTest.java b/modules/core/src/test/java/org/apache/ignite/p2p/ClassLoadingProblemExceptionTest.java index 44a39859e05b7..1af74a63c3340 100644 --- a/modules/core/src/test/java/org/apache/ignite/p2p/ClassLoadingProblemExceptionTest.java +++ b/modules/core/src/test/java/org/apache/ignite/p2p/ClassLoadingProblemExceptionTest.java @@ -197,8 +197,7 @@ private class TestCommunicationSpi extends TcpCommunicationSpi { GridCacheQueryRequest qryReq = (GridCacheQueryRequest)m; if (qryReq.deployInfo() != null) { - qryReq.prepare( - new GridDeploymentInfoBean( + qryReq.deploy(new GridDeploymentInfoBean( IgniteUuid.fromUuid(UUID.randomUUID()), qryReq.deployInfo().userVersion(), qryReq.deployInfo().deployMode(), diff --git a/modules/core/src/test/java/org/apache/ignite/plugin/extensions/communication/MessageMarshalOnceTest.java b/modules/core/src/test/java/org/apache/ignite/plugin/extensions/communication/MessageMarshalOnceTest.java new file mode 100644 index 0000000000000..fae5f22136b8e --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/plugin/extensions/communication/MessageMarshalOnceTest.java @@ -0,0 +1,149 @@ +/* + * 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.plugin.extensions.communication; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.CoreMessagesProvider; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.GridTopic; +import org.apache.ignite.internal.TestRecordingCommunicationSpi; +import org.apache.ignite.internal.managers.communication.GridIoPolicy; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.plugin.AbstractTestPluginProvider; +import org.apache.ignite.plugin.ExtensionRegistry; +import org.apache.ignite.plugin.PluginContext; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; + +/** + * Verifies the marshal-once-before-fan-out contract of the collection {@code send}: a message broadcast to N remote + * nodes is marshalled exactly once (prepared before the fan-out and reused for every destination), not once per + * destination. A counting marshaller is registered for a test message; broadcasting it to {@link #RMT_CNT} remote nodes + * must produce {@code RMT_CNT} sends but a single {@code marshal}. Counting the sends keeps the check honest (a + * lone send would also marshal once). The unmarshal-once counterpart lives in {@link MessageUnmarshalOnceTest}. + */ +public class MessageMarshalOnceTest extends GridCommonAbstractTest { + /** Direct type for the test message, past the core range. */ + private static final short TYPE = (short)(CoreMessagesProvider.MAX_MESSAGE_ID + 1); + + /** Number of remote destinations to broadcast to (a single marshal must serve all of them). */ + private static final int RMT_CNT = 4; + + /** Counts {@code marshal} invocations of {@link MarshalOnceCheckMessage} across the JVM. */ + private static final AtomicInteger MARSHAL_CNT = new AtomicInteger(); + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + cfg.setCommunicationSpi(new TestRecordingCommunicationSpi()); + + cfg.setPluginProviders(new AbstractTestPluginProvider() { + @Override public String name() { + return "marshal-once-test"; + } + + @Override public void initExtensions(PluginContext ctx, ExtensionRegistry registry) { + registry.registerExtension(MessageFactoryProvider.class, factory -> + factory.register(TYPE, MarshalOnceCheckMessage::new, new Serializer(), new CountingMarshaller())); + } + }); + + return cfg; + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + stopAllGrids(); + + super.afterTest(); + } + + /** @throws Exception If failed. */ + @Test + public void testBroadcastMarshalsExactlyOnce() throws Exception { + startGrids(RMT_CNT + 1); + + TestRecordingCommunicationSpi commSpi = TestRecordingCommunicationSpi.spi(grid(0)); + + commSpi.record(MarshalOnceCheckMessage.class); + + List rmts = new ArrayList<>(RMT_CNT); + + for (int i = 1; i <= RMT_CNT; i++) + rmts.add(grid(i).localNode()); + + MARSHAL_CNT.set(0); + + grid(0).context().io().sendToGridTopic(rmts, GridTopic.TOPIC_IO_TEST, new MarshalOnceCheckMessage(), + GridIoPolicy.PUBLIC_POOL); + + assertEquals("Broadcast must be sent to all " + RMT_CNT + " nodes", RMT_CNT, commSpi.recordedMessages(true).size()); + + assertEquals("A message broadcast to " + RMT_CNT + " nodes must be marshalled exactly once, not per destination", + 1, MARSHAL_CNT.get()); + } + + /** Fieldless message; only the registered marshaller's invocation count matters. */ + private static class MarshalOnceCheckMessage implements Message { + // No fields. + } + + /** Header-only serializer for the fieldless {@link MarshalOnceCheckMessage}. */ + private static class Serializer implements MessageSerializer { + /** {@inheritDoc} */ + @Override public boolean writeTo(MarshalOnceCheckMessage msg, MessageWriter writer) { + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(msg.directType())) + return false; + + writer.onHeaderWritten(); + } + + return true; + } + + /** {@inheritDoc} */ + @Override public boolean readFrom(MarshalOnceCheckMessage msg, MessageReader reader) { + return true; + } + } + + /** Marshaller that only counts {@code marshal} calls — no idempotency guard, so it counts raw invocations. */ + private static class CountingMarshaller implements MessageMarshaller { + /** {@inheritDoc} */ + @Override public void marshal(MarshalOnceCheckMessage msg, GridKernalContext kctx, CacheObjectContext nested) { + MARSHAL_CNT.incrementAndGet(); + } + + /** {@inheritDoc} */ + @Override public void unmarshal(MarshalOnceCheckMessage msg, GridKernalContext kctx, CacheObjectContext nested, + ClassLoader clsLdr) { + // No-op. + } + + /** {@inheritDoc} */ + @Override public void unmarshal(MarshalOnceCheckMessage msg, GridKernalContext kctx) { + // No-op. + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/plugin/extensions/communication/MessageUnmarshalOnceTest.java b/modules/core/src/test/java/org/apache/ignite/plugin/extensions/communication/MessageUnmarshalOnceTest.java new file mode 100644 index 0000000000000..996746c1a35f0 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/plugin/extensions/communication/MessageUnmarshalOnceTest.java @@ -0,0 +1,71 @@ +/* + * 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.plugin.extensions.communication; + +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; + +/** + * Verifies the no-double-unmarshal check itself, not its coverage: {@link MessageMarshaller.Dedup#firstUnmarshal} must + * detect a second finish-unmarshal of the same instance within one pass, while allowing the two legitimate passes + * (cache-free and cache-aware), and the check must be enabled for every test — otherwise the suite-wide guard would + * silently turn off and pass every test vacuously. The actual coverage (no real receive path unmarshals an instance + * twice in the same pass) comes from running the check across the whole suite via {@code GridAbstractTest}. + */ +public class MessageUnmarshalOnceTest extends GridCommonAbstractTest { + /** The suite-wide guard must be on, so a silently-disabled check cannot pass every test without verifying anything. */ + @Test + public void testCheckEnabled() { + assertTrue("IGNITE_MESSAGE_UNMARSHAL_ONCE_CHECK must be set for every test by GridAbstractTest", + MessageMarshaller.Dedup.ENABLED); + } + + /** A second finish-unmarshal of the same instance within one pass must be detected; the first must be allowed. */ + @Test + public void testSecondUnmarshalDetected() { + MarshallableMessage msg = new NoopMarshallableMessage(); + + assertTrue("First finish-unmarshal must be allowed", MessageMarshaller.Dedup.firstUnmarshal(msg, false)); + assertFalse("Second finish-unmarshal of the same instance in the same pass must be detected", + MessageMarshaller.Dedup.firstUnmarshal(msg, false)); + } + + /** The two legitimate passes (cache-free and cache-aware) over one instance must both be allowed. */ + @Test + public void testBothPassesAllowed() { + MarshallableMessage msg = new NoopMarshallableMessage(); + + assertTrue("Cache-free pass must be allowed", MessageMarshaller.Dedup.firstUnmarshal(msg, false)); + assertTrue("Cache-aware pass over the same instance must also be allowed", + MessageMarshaller.Dedup.firstUnmarshal(msg, true)); + } + + /** Minimal {@link MarshallableMessage}; only its identity matters to the check. */ + private static class NoopMarshallableMessage implements MarshallableMessage { + /** {@inheritDoc} */ + @Override public void marshal(Marshaller marsh) { + // No-op. + } + + /** {@inheritDoc} */ + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) { + // No-op. + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/spi/MessagesPluginProvider.java b/modules/core/src/test/java/org/apache/ignite/spi/MessagesPluginProvider.java index 865d9ba164444..d75f1c28e17c1 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/MessagesPluginProvider.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/MessagesPluginProvider.java @@ -53,7 +53,7 @@ public MessagesPluginProvider(Class... msgs) { } }; - f.register(directType, msgSupp, loadSerializer(msg, null, null)); + f.register(directType, msgSupp, loadSerializer(msg)); directType++; } diff --git a/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiSkipMessageSendTest.java b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiSkipMessageSendTest.java index aeba1e4d7c136..a9ea6d824db20 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiSkipMessageSendTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpiSkipMessageSendTest.java @@ -278,7 +278,7 @@ class CustomDiscoverySpi extends TcpDiscoverySpi { private final CountDownLatch netDisabledLatch = new CountDownLatch(1); /** {@inheritDoc} */ - @Override protected T readMessage(TcpDiscoveryIoSession ses, + @Override protected T readMessage(TcpDiscoveryIoSession ses, long timeout) throws IOException, IgniteCheckedException { if (netDisabled) { U.sleep(timeout); diff --git a/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TestDelayMessage.java b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TestDelayMessage.java index 4ed72c9905f40..70c8f724b60a7 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TestDelayMessage.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TestDelayMessage.java @@ -17,21 +17,12 @@ package org.apache.ignite.spi.communication.tcp; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.IgniteInterruptedCheckedException; -import org.apache.ignite.internal.MarshallableMessage; -import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.Message; /** Test message. */ -public class TestDelayMessage implements MarshallableMessage { +public class TestDelayMessage implements Message { /** */ - @Order(0) - int val; - - /** */ - private final int writeDelay; + final int writeDelay; /** */ public TestDelayMessage(int writeDelay) { @@ -42,21 +33,4 @@ public TestDelayMessage(int writeDelay) { public TestDelayMessage() { this(0); } - - /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { - if (writeDelay > 0) { - try { - U.sleep(writeDelay); - } - catch (IgniteInterruptedCheckedException ignored) { - // No-op. - } - } - } - - /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { - // No-op. - } } diff --git a/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TestDelayMessageSerializer.java b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TestDelayMessageSerializer.java new file mode 100644 index 0000000000000..f1e69422a9337 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/TestDelayMessageSerializer.java @@ -0,0 +1,53 @@ +/* + * 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.spi.communication.tcp; + +import org.apache.ignite.internal.IgniteInterruptedCheckedException; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; + +/** Serializer for {@link TestDelayMessage} that injects an optional write delay for testing. */ +public class TestDelayMessageSerializer implements MessageSerializer { + /** {@inheritDoc} */ + @Override public boolean writeTo(TestDelayMessage msg, MessageWriter writer) { + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(msg.directType())) + return false; + + writer.onHeaderWritten(); + } + + if (msg.writeDelay > 0) { + try { + U.sleep(msg.writeDelay); + } + catch (IgniteInterruptedCheckedException ignored) { + // No-op. + } + } + + return true; + } + + /** {@inheritDoc} */ + @Override public boolean readFrom(TestDelayMessage msg, MessageReader reader) { + return true; + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/BlockTcpDiscoverySpi.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/BlockTcpDiscoverySpi.java index 00ed5f205abd4..3c0445f0f94a8 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/BlockTcpDiscoverySpi.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/BlockTcpDiscoverySpi.java @@ -54,7 +54,7 @@ private synchronized void apply(ClusterNode addr, TcpDiscoveryAbstractMessage ms TcpDiscoveryCustomEventMessage cm = (TcpDiscoveryCustomEventMessage)msg; try { - cm.finishUnmarshal(marshaller(), U.gridClassLoader()); + cm.unmarshal(marshaller(), U.gridClassLoader()); assertNotNull(cm.message()); } diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java index 830e9aa27e4c5..59eedeb1ec757 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java @@ -26,15 +26,19 @@ import java.net.Socket; import java.nio.ByteBuffer; import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.CoreMessagesProvider; +import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.direct.DirectMessageWriter; import org.apache.ignite.internal.plugin.AbstractMarshallableMessageFactoryProvider; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; import org.apache.ignite.internal.util.IgniteUtils; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshallers; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.plugin.extensions.communication.MessageReader; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.plugin.extensions.communication.MessageWriter; @@ -48,6 +52,7 @@ import static org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION; import static org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_BLACKLIST; import static org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_WHITELIST; +import static org.apache.ignite.testframework.GridTestUtils.loadMarshaller; import static org.apache.ignite.testframework.GridTestUtils.loadSerializer; /** @@ -61,6 +66,12 @@ public class DiscoveryUnmarshalVulnerabilityTest extends GridCommonAbstractTest /** */ private LogListener lsnr; + /** */ + private MessageSerializer serializer; + + /** */ + private MessageMarshaller marshaller; + /** {@inheritDoc} */ @Override protected void beforeTest() throws Exception { super.beforeTest(); @@ -82,10 +93,13 @@ public class DiscoveryUnmarshalVulnerabilityTest extends GridCommonAbstractTest @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { MessageFactoryProvider msgFactoryProvider = new AbstractMarshallableMessageFactoryProvider() { @Override public void registerAll(MessageFactory factory) { + serializer = new MessageSerializerWrapper(this); + marshaller = new MessageMarshallerWrapper(this); + factory.register( - CoreMessagesProvider.MAX_MESSAGE_ID + 1, + (short)(CoreMessagesProvider.MAX_MESSAGE_ID + 1), ExploitMessage::new, - new MessageSerializerWrapper(this)); + serializer, marshaller); } }; @@ -214,7 +228,7 @@ private void attack(byte[] data) throws IOException { } /** */ - private byte[] serializedMessage() { + private byte[] serializedMessage() throws IgniteCheckedException { ByteBuffer buf = ByteBuffer.allocate(4096); MessageFactory msgFactory = ((TcpDiscoverySpi)grid().configuration().getDiscoverySpi()).messageFactory(); @@ -222,7 +236,11 @@ private byte[] serializedMessage() { DirectMessageWriter writer = new DirectMessageWriter(msgFactory); writer.setBuffer(buf); - writer.writeMessage(new ExploitMessage(new Exploit())); + ExploitMessage msg = new ExploitMessage(new Exploit()); + + MessageMarshaller.marshal(msgFactory, msg, grid().context(), null); + + writer.writeMessage(msg); return buf.flip().compact().array(); } @@ -270,9 +288,53 @@ private MessageSerializerWrapper(AbstractMarshallableMessageFactoryProvider prov /** */ private void initIfNecessary() { if (init.get() && init.compareAndSet(true, false)) - serde = loadSerializer(ExploitMessage.class, - U.field(provider, "dfltMarsh"), - U.field(provider, "resolvedClsLdr")); + serde = loadSerializer(ExploitMessage.class); + } + } + + /** Lazily-initialized {@link MessageMarshaller} wrapper resolved from the plugin provider. */ + private static class MessageMarshallerWrapper implements MessageMarshaller { + /** */ + private final AbstractMarshallableMessageFactoryProvider provider; + + /** */ + private final AtomicBoolean init = new AtomicBoolean(true); + + /** */ + private MessageMarshaller marsh; + + /** */ + private MessageMarshallerWrapper(AbstractMarshallableMessageFactoryProvider provider) { + this.provider = provider; + } + + /** {@inheritDoc} */ + @Override public void marshal(ExploitMessage msg, GridKernalContext kctx, CacheObjectContext nested) + throws IgniteCheckedException { + initIfNecessary(); + + marsh.marshal(msg, kctx, nested); + } + + /** {@inheritDoc} */ + @Override public void unmarshal(ExploitMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) + throws IgniteCheckedException { + initIfNecessary(); + + marsh.unmarshal(msg, kctx, nested, clsLdr); + } + + /** {@inheritDoc} */ + @Override public void unmarshal(ExploitMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + initIfNecessary(); + + marsh.unmarshal(msg, kctx); + } + + /** */ + private void initIfNecessary() { + if (init.get() && init.compareAndSet(true, false)) + marsh = loadMarshaller(ExploitMessage.class, U.field(provider, "dfltMarsh")); } } } diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ExploitMessage.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ExploitMessage.java index 182f91f826289..5223f0997f82e 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ExploitMessage.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ExploitMessage.java @@ -18,9 +18,9 @@ package org.apache.ignite.spi.discovery.tcp; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.apache.ignite.spi.discovery.tcp.DiscoveryUnmarshalVulnerabilityTest.Exploit; /** */ @@ -41,12 +41,12 @@ public ExploitMessage(Exploit exploit) { } /** {@inheritDoc} */ - @Override public void prepareMarshal(Marshaller marsh) throws IgniteCheckedException { + @Override public void marshal(Marshaller marsh) throws IgniteCheckedException { exploitBytes = marsh.marshal(exploit); } /** {@inheritDoc} */ - @Override public void finishUnmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { + @Override public void unmarshal(Marshaller marsh, ClassLoader clsLdr) throws IgniteCheckedException { exploit = marsh.unmarshal(exploitBytes, clsLdr); } } diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpClientDiscoverySpiFailureTimeoutSelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpClientDiscoverySpiFailureTimeoutSelfTest.java index 10645f5fc25d6..49ba4f269821d 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpClientDiscoverySpiFailureTimeoutSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpClientDiscoverySpiFailureTimeoutSelfTest.java @@ -36,6 +36,7 @@ import org.apache.ignite.internal.util.typedef.X; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgnitePredicate; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage; @@ -516,7 +517,7 @@ private static class TestTcpDiscoverySpi2 extends TcpDiscoverySpi { } /** {@inheritDoc} */ - @Override protected T readMessage(TcpDiscoveryIoSession ses, long timeout) + @Override protected T readMessage(TcpDiscoveryIoSession ses, long timeout) throws IOException, IgniteCheckedException { long currTimeout = getLocalNode().isClient() ? clientFailureDetectionTimeout() : failureDetectionTimeout(); diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java index 4920d029538a6..ac7901471fcba 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java @@ -2647,7 +2647,7 @@ private static class TestCustomerEventAckSpi extends TcpDiscoverySpi { try { TcpDiscoveryCustomEventMessage evtMsg = (TcpDiscoveryCustomEventMessage)msg; - evtMsg.finishUnmarshal(marshaller(), U.gridClassLoader()); + evtMsg.unmarshal(marshaller(), U.gridClassLoader()); DiscoveryCustomMessage custMsg = U.unwrapCustomMessage(evtMsg.message()); diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySslSecuredUnsecuredTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySslSecuredUnsecuredTest.java index dcf9931ef9236..79b6962db51e6 100644 --- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySslSecuredUnsecuredTest.java +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySslSecuredUnsecuredTest.java @@ -23,6 +23,7 @@ import javax.net.ssl.SSLException; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; @@ -174,7 +175,7 @@ private FailDiscoverySpi(final boolean plain) { } /** {@inheritDoc} */ - @Override protected T readMessage(final TcpDiscoveryIoSession ses, + @Override protected T readMessage(final TcpDiscoveryIoSession ses, final long timeout) throws IOException, IgniteCheckedException { if (cnt-- > 0) { if (plain) diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java index 01380265c96d7..7f0ed8b0af031 100644 --- a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java @@ -102,7 +102,6 @@ import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.IgniteInterruptedCheckedException; import org.apache.ignite.internal.IgniteKernal; -import org.apache.ignite.internal.MarshallableMessage; import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.GridCacheContext; @@ -130,7 +129,9 @@ import org.apache.ignite.lang.IgniteInClosure; import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MarshallableMessage; import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; import org.apache.ignite.spi.communication.tcp.internal.GridNioServerWrapper; @@ -2704,28 +2705,36 @@ public static void skipCommNioServerRead(IgniteEx ignite, boolean skip) { } /** */ - public static MessageSerializer loadSerializer(Class msgCls, - @Nullable Marshaller dfltMarsh, @Nullable ClassLoader dfltClsLdr) { + public static MessageSerializer loadSerializer(Class msgCls) { try { - boolean isMarshallable = MarshallableMessage.class.isAssignableFrom(msgCls); + Class serCls = U.gridClassLoader() + .loadClass(msgCls.getPackage().getName() + "." + msgCls.getSimpleName() + "Serializer"); - String clsPref = msgCls.getSimpleName() + (isMarshallable ? "Marshallable" : ""); + return (MessageSerializer)U.newInstance(serCls); + } + catch (Exception e) { + throw new RuntimeException("Unable to find serializer for message: " + msgCls, e); + } + } - Class serCls = U.gridClassLoader() - .loadClass(msgCls.getPackage().getName() + "." + clsPref + "Serializer"); + /** Loads the generated {@code *Marshaller} class for {@code msgCls} and instantiates it with {@code dfltMarsh}. */ + public static MessageMarshaller loadMarshaller(Class msgCls, + @Nullable Marshaller dfltMarsh) { + try { + Class marshallerCls = U.gridClassLoader() + .loadClass(msgCls.getPackage().getName() + "." + msgCls.getSimpleName() + "Marshaller"); - Marshaller marsh = dfltMarsh != null ? dfltMarsh : jdk(); - ClassLoader cldLdr = dfltClsLdr != null ? dfltClsLdr : U.gridClassLoader(); + boolean isMarshallable = MarshallableMessage.class.isAssignableFrom(msgCls); - Object msgSer = isMarshallable ? - serCls.getConstructor(Marshaller.class, ClassLoader.class) - .newInstance(marsh, cldLdr) : - U.newInstance(serCls); + if (isMarshallable) { + Marshaller marsh = dfltMarsh != null ? dfltMarsh : jdk(); + return (MessageMarshaller)marshallerCls.getConstructor(Marshaller.class).newInstance(marsh); + } - return (MessageSerializer)msgSer; + return (MessageMarshaller)U.newInstance(marshallerCls); } catch (Exception e) { - throw new RuntimeException("Unable to find serializer for message: " + msgCls, e); + throw new RuntimeException("Unable to find marshaller for message: " + msgCls, e); } } diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java index 5029cb64a8953..c214494931ab7 100755 --- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java @@ -159,6 +159,7 @@ import static org.apache.ignite.IgniteSystemProperties.IGNITE_CLIENT_CACHE_CHANGE_MESSAGE_TIMEOUT; import static org.apache.ignite.IgniteSystemProperties.IGNITE_DISCO_FAILED_CLIENT_RECONNECT_DELAY; import static org.apache.ignite.IgniteSystemProperties.IGNITE_LOG_CLASSPATH_CONTENT_ON_STARTUP; +import static org.apache.ignite.IgniteSystemProperties.IGNITE_MESSAGE_UNMARSHAL_ONCE_CHECK; import static org.apache.ignite.IgniteSystemProperties.IGNITE_TEST_ENV; import static org.apache.ignite.IgniteSystemProperties.IGNITE_TO_STRING_INCLUDE_SENSITIVE; import static org.apache.ignite.IgniteSystemProperties.IGNITE_UPDATE_NOTIFIER; @@ -291,6 +292,7 @@ public String getName() { System.setProperty(IGNITE_CLIENT_CACHE_CHANGE_MESSAGE_TIMEOUT, "1000"); System.setProperty(IGNITE_LOG_CLASSPATH_CONTENT_ON_STARTUP, "false"); System.setProperty(IGNITE_TEST_ENV, "true"); + System.setProperty(IGNITE_MESSAGE_UNMARSHAL_ONCE_CHECK, "true"); S.setIncludeSensitiveSupplier(() -> getBoolean(IGNITE_TO_STRING_INCLUDE_SENSITIVE, true)); diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java index 337dd99ed4f95..c33dc0e7a33e0 100644 --- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java @@ -37,6 +37,7 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.plugin.PluginProvider; +import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.spi.metric.noop.NoopMetricExporterSpi; import org.apache.ignite.testframework.GridTestUtils; @@ -46,6 +47,9 @@ * Test context. */ public class GridTestKernalContext extends GridKernalContextImpl { + /** Message factory override for tests; when non-null, replaces the default factory. */ + public MessageFactory messageFactory; + /** * @param log Logger to use in context config. */ @@ -115,6 +119,11 @@ public void stop(boolean cancel) throws IgniteCheckedException { } } + /** {@inheritDoc} */ + @Override public MessageFactory messageFactory() { + return messageFactory != null ? messageFactory : super.messageFactory(); + } + /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridTestKernalContext.class, this, super.toString()); diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java index f4d278c1c8c11..605d06f9d48ac 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java @@ -36,7 +36,9 @@ import org.apache.ignite.internal.IgniteSlowClientDetectionSelfTest; import org.apache.ignite.internal.TransactionsMXBeanImplTest; import org.apache.ignite.internal.codegen.IgniteDataTransferObjectProcessorTest; +import org.apache.ignite.internal.codegen.MarshallerCacheFreeUnmarshalTest; import org.apache.ignite.internal.codegen.MessageProcessorTest; +import org.apache.ignite.internal.codegen.MessageSerializationArchitectureTest; import org.apache.ignite.internal.managers.communication.CompressedMessageTest; import org.apache.ignite.internal.managers.communication.DefaultEnumMapperTest; import org.apache.ignite.internal.managers.communication.ErrorMessageSelfTest; @@ -71,6 +73,8 @@ import org.apache.ignite.messaging.GridMessagingSelfTest; import org.apache.ignite.messaging.IgniteMessagingSendAsyncTest; import org.apache.ignite.messaging.IgniteMessagingWithClientTest; +import org.apache.ignite.plugin.extensions.communication.MessageMarshalOnceTest; +import org.apache.ignite.plugin.extensions.communication.MessageUnmarshalOnceTest; import org.apache.ignite.spi.GridSpiLocalHostInjectionTest; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTestSelfTest; import org.apache.ignite.testframework.junits.multijvm.JavaVersionCommandParserTest; @@ -151,6 +155,10 @@ ClientSessionOutboundQueueLimitTest.class, MessageProcessorTest.class, + MessageMarshalOnceTest.class, + MessageUnmarshalOnceTest.class, + MarshallerCacheFreeUnmarshalTest.class, + MessageSerializationArchitectureTest.class, ErrorMessageSelfTest.class, DefaultEnumMapperTest.class, IgniteDataTransferObjectProcessorTest.class, diff --git a/modules/core/src/test/resources/codegen/ChildMessageMarshaller.java b/modules/core/src/test/resources/codegen/ChildMessageMarshaller.java new file mode 100644 index 0000000000000..c9dbf11137bac --- /dev/null +++ b/modules/core/src/test/resources/codegen/ChildMessageMarshaller.java @@ -0,0 +1,48 @@ +/* + * 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; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.ChildMessage; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class ChildMessageMarshaller implements MessageMarshaller { + /** */ + public ChildMessageMarshaller() { + } + + /** */ + @Override public void marshal(ChildMessage msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException { + } + + /** */ + @Override public void unmarshal(ChildMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + } + + /** */ + @Override public void unmarshal(ChildMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/ChildMessageSerializer.java b/modules/core/src/test/resources/codegen/ChildMessageSerializer.java index 9ca035db40488..6c06862cfeb05 100644 --- a/modules/core/src/test/resources/codegen/ChildMessageSerializer.java +++ b/modules/core/src/test/resources/codegen/ChildMessageSerializer.java @@ -29,6 +29,10 @@ * @see org.apache.ignite.internal.MessageProcessor */ public class ChildMessageSerializer implements MessageSerializer { + /** */ + public ChildMessageSerializer() { + } + /** */ @Override public boolean writeTo(ChildMessage msg, MessageWriter writer) { if (!writer.isHeaderWritten()) { diff --git a/modules/core/src/test/resources/codegen/CustomMapperEnumFieldsMessageMarshaller.java b/modules/core/src/test/resources/codegen/CustomMapperEnumFieldsMessageMarshaller.java new file mode 100644 index 0000000000000..0b04c22489ab0 --- /dev/null +++ b/modules/core/src/test/resources/codegen/CustomMapperEnumFieldsMessageMarshaller.java @@ -0,0 +1,48 @@ +/* + * 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; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.CustomMapperEnumFieldsMessage; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class CustomMapperEnumFieldsMessageMarshaller implements MessageMarshaller { + /** */ + public CustomMapperEnumFieldsMessageMarshaller() { + } + + /** */ + @Override public void marshal(CustomMapperEnumFieldsMessage msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException { + } + + /** */ + @Override public void unmarshal(CustomMapperEnumFieldsMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + } + + /** */ + @Override public void unmarshal(CustomMapperEnumFieldsMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/CustomMapperEnumFieldsMessageSerializer.java b/modules/core/src/test/resources/codegen/CustomMapperEnumFieldsMessageSerializer.java index db939d0825792..6dea5109f8b5f 100644 --- a/modules/core/src/test/resources/codegen/CustomMapperEnumFieldsMessageSerializer.java +++ b/modules/core/src/test/resources/codegen/CustomMapperEnumFieldsMessageSerializer.java @@ -34,6 +34,10 @@ public class CustomMapperEnumFieldsMessageSerializer implements MessageSerialize /** */ private final EnumMapper transactionIsolationMapper = new TransactionIsolationEnumMapper(); + /** */ + public CustomMapperEnumFieldsMessageSerializer() { + } + /** */ @Override public boolean writeTo(CustomMapperEnumFieldsMessage msg, MessageWriter writer) { if (!writer.isHeaderWritten()) { @@ -68,4 +72,4 @@ public class CustomMapperEnumFieldsMessageSerializer implements MessageSerialize return true; } -} \ No newline at end of file +} diff --git a/modules/core/src/test/resources/codegen/DefaultMapperEnumFieldsMessageMarshaller.java b/modules/core/src/test/resources/codegen/DefaultMapperEnumFieldsMessageMarshaller.java new file mode 100644 index 0000000000000..21df8e0eb8de0 --- /dev/null +++ b/modules/core/src/test/resources/codegen/DefaultMapperEnumFieldsMessageMarshaller.java @@ -0,0 +1,48 @@ +/* + * 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; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.DefaultMapperEnumFieldsMessage; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class DefaultMapperEnumFieldsMessageMarshaller implements MessageMarshaller { + /** */ + public DefaultMapperEnumFieldsMessageMarshaller() { + } + + /** */ + @Override public void marshal(DefaultMapperEnumFieldsMessage msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException { + } + + /** */ + @Override public void unmarshal(DefaultMapperEnumFieldsMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + } + + /** */ + @Override public void unmarshal(DefaultMapperEnumFieldsMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/DefaultMapperEnumFieldsMessageSerializer.java b/modules/core/src/test/resources/codegen/DefaultMapperEnumFieldsMessageSerializer.java index 245f1f29ae8e5..7d3859fee4a35 100644 --- a/modules/core/src/test/resources/codegen/DefaultMapperEnumFieldsMessageSerializer.java +++ b/modules/core/src/test/resources/codegen/DefaultMapperEnumFieldsMessageSerializer.java @@ -36,6 +36,10 @@ public class DefaultMapperEnumFieldsMessageSerializer implements MessageSerializ /** */ private final TransactionIsolation[] transactionIsolationVals = TransactionIsolation.values(); + /** */ + public DefaultMapperEnumFieldsMessageSerializer() { + } + /** */ @Override public boolean writeTo(DefaultMapperEnumFieldsMessage msg, MessageWriter writer) { if (!writer.isHeaderWritten()) { diff --git a/modules/core/src/test/resources/codegen/NioFieldOnNonMessageMessage.java b/modules/core/src/test/resources/codegen/NioFieldOnNonMessageMessage.java new file mode 100644 index 0000000000000..a8ac50154d9df --- /dev/null +++ b/modules/core/src/test/resources/codegen/NioFieldOnNonMessageMessage.java @@ -0,0 +1,30 @@ +/* + * 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; + +import org.apache.ignite.plugin.extensions.communication.Message; + +public class NioFieldOnNonMessageMessage implements Message { + @NioField + @Order(0) + int id; + + public short directType() { + return 0; + } +} diff --git a/modules/core/src/test/resources/codegen/TestCacheIdMessage.java b/modules/core/src/test/resources/codegen/TestCacheIdMessage.java new file mode 100644 index 0000000000000..749e5fd007b60 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestCacheIdMessage.java @@ -0,0 +1,47 @@ +/* + * 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; + +import java.util.Collection; +import java.util.List; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; +import org.apache.ignite.internal.processors.cache.KeyCacheObject; +import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry; + +public class TestCacheIdMessage extends GridCacheIdMessage { + @Order(0) + KeyCacheObject key; + + @Order(1) + CacheObject val; + + @Order(2) + List keys; + + @Order(3) + Collection writes; + + public short directType() { + return 0; + } + + @Override public boolean addDeploymentInfo() { + return true; + } +} diff --git a/modules/core/src/test/resources/codegen/TestCacheIdMessageDeployer.java b/modules/core/src/test/resources/codegen/TestCacheIdMessageDeployer.java new file mode 100644 index 0000000000000..00200f0d59c18 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestCacheIdMessageDeployer.java @@ -0,0 +1,44 @@ +/* + * 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; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.TestCacheIdMessage; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; +import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestCacheIdMessageDeployer implements GridCacheMessageDeployer { + /** */ + @Override public void deploy(TestCacheIdMessage msg, GridCacheSharedContext ctx) throws IgniteCheckedException { + GridCacheContext cctx = ctx.cacheContext(msg.cacheId()); + + msg.deployCacheObject(msg.key, cctx); + + msg.deployCacheObject(msg.val, cctx); + + msg.deployCacheObjects(msg.keys, cctx); + + msg.deployTx(msg.writes, ctx); + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestCollectionsMessage.java b/modules/core/src/test/resources/codegen/TestCollectionsMessage.java index 312d5e91f8122..16d384b8e6a22 100644 --- a/modules/core/src/test/resources/codegen/TestCollectionsMessage.java +++ b/modules/core/src/test/resources/codegen/TestCollectionsMessage.java @@ -22,6 +22,7 @@ import java.util.Set; import java.util.UUID; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheObject; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.GridLongList; import org.apache.ignite.lang.IgniteUuid; @@ -103,6 +104,9 @@ public class TestCollectionsMessage implements Message { @Order(24) Set bitSetSet; + @Order(25) + Set cacheObjectSet; + public short directType() { return 0; } diff --git a/modules/core/src/test/resources/codegen/TestCollectionsMessageMarshaller.java b/modules/core/src/test/resources/codegen/TestCollectionsMessageMarshaller.java new file mode 100644 index 0000000000000..cfb651719d1fb --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestCollectionsMessageMarshaller.java @@ -0,0 +1,101 @@ +/* + * 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; + +import java.lang.Boolean; +import java.lang.Byte; +import java.lang.Character; +import java.lang.Double; +import java.lang.Float; +import java.lang.Integer; +import java.lang.Long; +import java.lang.Short; +import java.lang.String; +import java.util.BitSet; +import java.util.Collection; +import java.util.UUID; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.TestCollectionsMessage; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.GridLongList; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.lang.IgniteUuid; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestCollectionsMessageMarshaller implements MessageMarshaller { + /** */ + public TestCollectionsMessageMarshaller() { + } + + /** */ + @Override public void marshal(TestCollectionsMessage msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException { + CacheObjectContext ctx = nested; + + if (msg.messageList != null) { + for (GridCacheVersion e : (Collection)msg.messageList) { + if (e != null) + MessageMarshaller.marshal(kctx.messageFactory(), e, kctx, ctx); + } + } + + if (msg.cacheObjectSet != null) { + for (CacheObject e : (Collection)msg.cacheObjectSet) { + if (e != null && ctx != null) + e.marshal(ctx); + } + } + } + + /** */ + @Override public void unmarshal(TestCollectionsMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + CacheObjectContext ctx = nested; + + if (msg.messageList != null) { + for (GridCacheVersion e : (Collection)msg.messageList) { + if (e != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), e, kctx, ctx, clsLdr); + } + } + + if (msg.cacheObjectSet != null) { + for (CacheObject e : (Collection)msg.cacheObjectSet) { + if (e != null && ctx != null) + e.unmarshal(ctx, clsLdr); + } + } + } + + /** */ + @Override public void unmarshal(TestCollectionsMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + if (msg.messageList != null) { + for (GridCacheVersion e : (Collection)msg.messageList) { + if (e != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), e, kctx); + } + } + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestCollectionsMessageSerializer.java b/modules/core/src/test/resources/codegen/TestCollectionsMessageSerializer.java index 329f334337488..1741e3161433b 100644 --- a/modules/core/src/test/resources/codegen/TestCollectionsMessageSerializer.java +++ b/modules/core/src/test/resources/codegen/TestCollectionsMessageSerializer.java @@ -32,56 +32,62 @@ */ public class TestCollectionsMessageSerializer implements MessageSerializer { /** */ - private final static MessageCollectionType affTopVersionListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION), false); + private static final MessageCollectionType affTopVersionListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION), false); /** */ - private final static MessageCollectionType bitSetListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BIT_SET), false); + private static final MessageCollectionType bitSetListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BIT_SET), false); /** */ - private final static MessageCollectionType bitSetSetCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BIT_SET), true); + private static final MessageCollectionType bitSetSetCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BIT_SET), true); /** */ - private final static MessageCollectionType booleanArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BOOLEAN_ARR), false); + private static final MessageCollectionType booleanArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BOOLEAN_ARR), false); /** */ - private final static MessageCollectionType boxedBooleanListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BOOLEAN), false); + private static final MessageCollectionType boxedBooleanListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BOOLEAN), false); /** */ - private final static MessageCollectionType boxedByteListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BYTE), false); + private static final MessageCollectionType boxedByteListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BYTE), false); /** */ - private final static MessageCollectionType boxedCharListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.CHAR), false); + private static final MessageCollectionType boxedCharListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.CHAR), false); /** */ - private final static MessageCollectionType boxedDoubleListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.DOUBLE), false); + private static final MessageCollectionType boxedDoubleListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.DOUBLE), false); /** */ - private final static MessageCollectionType boxedFloatListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.FLOAT), false); + private static final MessageCollectionType boxedFloatListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.FLOAT), false); /** */ - private final static MessageCollectionType boxedIntListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.INT), false); + private static final MessageCollectionType boxedIntListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.INT), false); /** */ - private final static MessageCollectionType boxedIntegerSetCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.INT), true); + private static final MessageCollectionType boxedIntegerSetCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.INT), true); /** */ - private final static MessageCollectionType boxedLongListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.LONG), false); + private static final MessageCollectionType boxedLongListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.LONG), false); /** */ - private final static MessageCollectionType boxedShortListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.SHORT), false); + private static final MessageCollectionType boxedShortListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.SHORT), false); /** */ - private final static MessageCollectionType byteArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BYTE_ARR), false); + private static final MessageCollectionType byteArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BYTE_ARR), false); /** */ - private final static MessageCollectionType charArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.CHAR_ARR), false); + private static final MessageCollectionType cacheObjectSetCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.CACHE_OBJECT), true); /** */ - private final static MessageCollectionType doubleArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.DOUBLE_ARR), false); + private static final MessageCollectionType charArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.CHAR_ARR), false); /** */ - private final static MessageCollectionType floatArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.FLOAT_ARR), false); + private static final MessageCollectionType doubleArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.DOUBLE_ARR), false); /** */ - private final static MessageCollectionType gridLongListListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.GRID_LONG_LIST), false); + private static final MessageCollectionType floatArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.FLOAT_ARR), false); /** */ - private final static MessageCollectionType igniteUuidListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.IGNITE_UUID), false); + private static final MessageCollectionType gridLongListListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.GRID_LONG_LIST), false); /** */ - private final static MessageCollectionType intArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.INT_ARR), false); + private static final MessageCollectionType igniteUuidListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.IGNITE_UUID), false); /** */ - private final static MessageCollectionType longArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.LONG_ARR), false); + private static final MessageCollectionType intArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.INT_ARR), false); /** */ - private final static MessageCollectionType messageListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.MSG), false); + private static final MessageCollectionType longArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.LONG_ARR), false); /** */ - private final static MessageCollectionType shortArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.SHORT_ARR), false); + private static final MessageCollectionType messageListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.MSG), false); /** */ - private final static MessageCollectionType stringListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.STRING), false); + private static final MessageCollectionType shortArrayListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.SHORT_ARR), false); /** */ - private final static MessageCollectionType uuidListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.UUID), false); + private static final MessageCollectionType stringListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.STRING), false); + /** */ + private static final MessageCollectionType uuidListCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.UUID), false); + /** */ + public TestCollectionsMessageSerializer() { + } + /** */ @Override public boolean writeTo(TestCollectionsMessage msg, MessageWriter writer) { if (!writer.isHeaderWritten()) { @@ -241,6 +247,12 @@ public class TestCollectionsMessageSerializer implements MessageSerializer ctx) throws IgniteCheckedException; +public class TestDeployableMessage extends GridCacheIdMessage implements DeployableMessage { + @Order(0) + KeyCacheObject key; - /** - * Prepares the message before processing. - * - * @param ctx Cache shared context. - * @param clsLdr Class loader. - */ - void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader clsLdr) throws IgniteCheckedException; + public short directType() { + return 0; + } + + @Override public boolean addDeploymentInfo() { + return true; + } + + @Override public void deploy(GridCacheSharedContext ctx) throws IgniteCheckedException { + // Custom deployment that cannot be inferred from field types. + } } diff --git a/modules/core/src/test/resources/codegen/TestDeployableMessageDeployer.java b/modules/core/src/test/resources/codegen/TestDeployableMessageDeployer.java new file mode 100644 index 0000000000000..f4705cafac8eb --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestDeployableMessageDeployer.java @@ -0,0 +1,40 @@ +/* + * 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; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.TestDeployableMessage; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; +import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestDeployableMessageDeployer implements GridCacheMessageDeployer { + /** */ + @Override public void deploy(TestDeployableMessage msg, GridCacheSharedContext ctx) throws IgniteCheckedException { + GridCacheContext cctx = ctx.cacheContext(msg.cacheId()); + + msg.deployCacheObject(msg.key, cctx); + + msg.deploy(ctx); + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMapMessage.java b/modules/core/src/test/resources/codegen/TestMapMessage.java index 71a20da923709..f33fd2cc0a679 100644 --- a/modules/core/src/test/resources/codegen/TestMapMessage.java +++ b/modules/core/src/test/resources/codegen/TestMapMessage.java @@ -22,6 +22,8 @@ import java.util.Map; import java.util.UUID; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.GridLongList; import org.apache.ignite.lang.IgniteUuid; @@ -103,6 +105,9 @@ public class TestMapMessage implements Message { @Order(24) Map>> gridlistDoubleMapUuidMap; + @Order(25) + Map>> gridCacheObjectMap; + public short directType() { return 0; } diff --git a/modules/core/src/test/resources/codegen/TestMapMessageMarshaller.java b/modules/core/src/test/resources/codegen/TestMapMessageMarshaller.java new file mode 100644 index 0000000000000..23902ee640919 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMapMessageMarshaller.java @@ -0,0 +1,128 @@ +/* + * 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; + +import java.lang.Boolean; +import java.lang.Byte; +import java.lang.Character; +import java.lang.Double; +import java.lang.Float; +import java.lang.Integer; +import java.lang.Long; +import java.lang.Short; +import java.lang.String; +import java.util.BitSet; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.TestMapMessage; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.processors.cache.KeyCacheObject; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.GridLongList; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.lang.IgniteUuid; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMapMessageMarshaller implements MessageMarshaller { + /** */ + public TestMapMessageMarshaller() { + } + + /** */ + @Override public void marshal(TestMapMessage msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException { + CacheObjectContext ctx = nested; + + if (msg.messageBoxedDoubleMap != null) { + for (GridCacheVersion e : ((Collection)msg.messageBoxedDoubleMap.keySet())) { + if (e != null) + MessageMarshaller.marshal(kctx.messageFactory(), e, kctx, ctx); + } + } + + if (msg.gridCacheObjectMap != null) { + for (KeyCacheObject e : ((Collection)msg.gridCacheObjectMap.keySet())) { + if (e != null && ctx != null) + e.marshal(ctx); + } + for (Map e : ((Collection)msg.gridCacheObjectMap.values())) { + if (e != null) { + for (List e1 : ((Collection)e.values())) { + if (e1 != null) { + for (CacheObject e2 : (Collection)e1) { + if (e2 != null && ctx != null) + e2.marshal(ctx); + } + } + } + } + } + } + } + + /** */ + @Override public void unmarshal(TestMapMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + CacheObjectContext ctx = nested; + + if (msg.messageBoxedDoubleMap != null) { + for (GridCacheVersion e : ((Collection)msg.messageBoxedDoubleMap.keySet())) { + if (e != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), e, kctx, ctx, clsLdr); + } + } + + if (msg.gridCacheObjectMap != null) { + for (KeyCacheObject e : ((Collection)msg.gridCacheObjectMap.keySet())) { + if (e != null && ctx != null) + e.unmarshal(ctx, clsLdr); + } + for (Map e : ((Collection)msg.gridCacheObjectMap.values())) { + if (e != null) { + for (List e1 : ((Collection)e.values())) { + if (e1 != null) { + for (CacheObject e2 : (Collection)e1) { + if (e2 != null && ctx != null) + e2.unmarshal(ctx, clsLdr); + } + } + } + } + } + } + } + + /** */ + @Override public void unmarshal(TestMapMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + if (msg.messageBoxedDoubleMap != null) { + for (GridCacheVersion e : ((Collection)msg.messageBoxedDoubleMap.keySet())) { + if (e != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), e, kctx); + } + } + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMapMessageSerializer.java b/modules/core/src/test/resources/codegen/TestMapMessageSerializer.java index b2e66053653df..7cacb98f36858 100644 --- a/modules/core/src/test/resources/codegen/TestMapMessageSerializer.java +++ b/modules/core/src/test/resources/codegen/TestMapMessageSerializer.java @@ -33,56 +33,62 @@ */ public class TestMapMessageSerializer implements MessageSerializer { /** */ - private final static MessageMapType affTopVersionIgniteUuidMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION), new MessageItemType(MessageCollectionItemType.IGNITE_UUID), false); + private static final MessageMapType affTopVersionIgniteUuidMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION), new MessageItemType(MessageCollectionItemType.IGNITE_UUID), false); /** */ - private final static MessageMapType bitSetUuidMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.BIT_SET), new MessageItemType(MessageCollectionItemType.UUID), false); + private static final MessageMapType bitSetUuidMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.BIT_SET), new MessageItemType(MessageCollectionItemType.UUID), false); /** */ - private final static MessageMapType booleanArrayBoxedLongMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.BOOLEAN_ARR), new MessageItemType(MessageCollectionItemType.LONG), false); + private static final MessageMapType booleanArrayBoxedLongMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.BOOLEAN_ARR), new MessageItemType(MessageCollectionItemType.LONG), false); /** */ - private final static MessageMapType boxedBooleanAffTopVersionMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.BOOLEAN), new MessageItemType(MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION), false); + private static final MessageMapType boxedBooleanAffTopVersionMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.BOOLEAN), new MessageItemType(MessageCollectionItemType.AFFINITY_TOPOLOGY_VERSION), false); /** */ - private final static MessageMapType boxedByteBoxedBooleanMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.BYTE), new MessageItemType(MessageCollectionItemType.BOOLEAN), false); + private static final MessageMapType boxedByteBoxedBooleanMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.BYTE), new MessageItemType(MessageCollectionItemType.BOOLEAN), false); /** */ - private final static MessageMapType boxedCharBoxedLongMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.CHAR), new MessageItemType(MessageCollectionItemType.LONG), false); + private static final MessageMapType boxedCharBoxedLongMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.CHAR), new MessageItemType(MessageCollectionItemType.LONG), false); /** */ - private final static MessageMapType boxedDoubleBoxedFloatMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.DOUBLE), new MessageItemType(MessageCollectionItemType.FLOAT), false); + private static final MessageMapType boxedDoubleBoxedFloatMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.DOUBLE), new MessageItemType(MessageCollectionItemType.FLOAT), false); /** */ - private final static MessageMapType boxedFloatBoxedCharMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.FLOAT), new MessageItemType(MessageCollectionItemType.CHAR), false); + private static final MessageMapType boxedFloatBoxedCharMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.FLOAT), new MessageItemType(MessageCollectionItemType.CHAR), false); /** */ - private final static MessageMapType boxedIntBoxedShortMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.INT), new MessageItemType(MessageCollectionItemType.SHORT), false); + private static final MessageMapType boxedIntBoxedShortMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.INT), new MessageItemType(MessageCollectionItemType.SHORT), false); /** */ - private final static MessageMapType boxedLongBoxedIntMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.LONG), new MessageItemType(MessageCollectionItemType.INT), false); + private static final MessageMapType boxedLongBoxedIntMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.LONG), new MessageItemType(MessageCollectionItemType.INT), false); /** */ - private final static MessageMapType boxedShortBoxedByteMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.SHORT), new MessageItemType(MessageCollectionItemType.BYTE), false); + private static final MessageMapType boxedShortBoxedByteMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.SHORT), new MessageItemType(MessageCollectionItemType.BYTE), false); /** */ - private final static MessageMapType byteArrayBooleanArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.BYTE_ARR), new MessageItemType(MessageCollectionItemType.BOOLEAN_ARR), false); + private static final MessageMapType byteArrayBooleanArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.BYTE_ARR), new MessageItemType(MessageCollectionItemType.BOOLEAN_ARR), false); /** */ - private final static MessageMapType charArrayLongArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.CHAR_ARR), new MessageItemType(MessageCollectionItemType.LONG_ARR), false); + private static final MessageMapType charArrayLongArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.CHAR_ARR), new MessageItemType(MessageCollectionItemType.LONG_ARR), false); /** */ - private final static MessageMapType doubleArrayFloatArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.DOUBLE_ARR), new MessageItemType(MessageCollectionItemType.FLOAT_ARR), false); + private static final MessageMapType doubleArrayFloatArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.DOUBLE_ARR), new MessageItemType(MessageCollectionItemType.FLOAT_ARR), false); /** */ - private final static MessageMapType floatArrayCharArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.FLOAT_ARR), new MessageItemType(MessageCollectionItemType.CHAR_ARR), false); + private static final MessageMapType floatArrayCharArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.FLOAT_ARR), new MessageItemType(MessageCollectionItemType.CHAR_ARR), false); /** */ - private final static MessageMapType gridLongListIntegerMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.GRID_LONG_LIST), new MessageItemType(MessageCollectionItemType.INT), false); + private static final MessageMapType gridCacheObjectMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.KEY_CACHE_OBJECT), new MessageMapType(new MessageItemType(MessageCollectionItemType.UUID), new MessageCollectionType(new MessageItemType(MessageCollectionItemType.CACHE_OBJECT), false), false), false); /** */ - private final static MessageMapType gridlistDoubleMapUuidMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.GRID_LONG_LIST), new MessageMapType(new MessageItemType(MessageCollectionItemType.UUID), new MessageCollectionType(new MessageItemType(MessageCollectionItemType.DOUBLE), false), false), false); + private static final MessageMapType gridLongListIntegerMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.GRID_LONG_LIST), new MessageItemType(MessageCollectionItemType.INT), false); /** */ - private final static MessageMapType igniteUuidBitSetMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.IGNITE_UUID), new MessageItemType(MessageCollectionItemType.BIT_SET), false); + private static final MessageMapType gridlistDoubleMapUuidMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.GRID_LONG_LIST), new MessageMapType(new MessageItemType(MessageCollectionItemType.UUID), new MessageCollectionType(new MessageItemType(MessageCollectionItemType.DOUBLE), false), false), false); /** */ - private final static MessageMapType intArrayShortArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.INT_ARR), new MessageItemType(MessageCollectionItemType.SHORT_ARR), false); + private static final MessageMapType igniteUuidBitSetMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.IGNITE_UUID), new MessageItemType(MessageCollectionItemType.BIT_SET), false); /** */ - private final static MessageMapType integerGridLongListMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.INT), new MessageItemType(MessageCollectionItemType.GRID_LONG_LIST), false); + private static final MessageMapType intArrayShortArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.INT_ARR), new MessageItemType(MessageCollectionItemType.SHORT_ARR), false); /** */ - private final static MessageMapType longArrayIntArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.LONG_ARR), new MessageItemType(MessageCollectionItemType.INT_ARR), false); + private static final MessageMapType integerGridLongListMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.INT), new MessageItemType(MessageCollectionItemType.GRID_LONG_LIST), false); /** */ - private final static MessageMapType messageBoxedDoubleMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.MSG), new MessageItemType(MessageCollectionItemType.DOUBLE), false); + private static final MessageMapType longArrayIntArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.LONG_ARR), new MessageItemType(MessageCollectionItemType.INT_ARR), false); /** */ - private final static MessageMapType shortArrayByteArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.SHORT_ARR), new MessageItemType(MessageCollectionItemType.BYTE_ARR), false); + private static final MessageMapType messageBoxedDoubleMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.MSG), new MessageItemType(MessageCollectionItemType.DOUBLE), false); /** */ - private final static MessageMapType stringDoubleArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.STRING), new MessageItemType(MessageCollectionItemType.DOUBLE_ARR), false); + private static final MessageMapType shortArrayByteArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.SHORT_ARR), new MessageItemType(MessageCollectionItemType.BYTE_ARR), false); /** */ - private final static MessageMapType uuidStringMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.UUID), new MessageItemType(MessageCollectionItemType.STRING), false); + private static final MessageMapType stringDoubleArrayMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.STRING), new MessageItemType(MessageCollectionItemType.DOUBLE_ARR), false); + /** */ + private static final MessageMapType uuidStringMapCollDesc = new MessageMapType(new MessageItemType(MessageCollectionItemType.UUID), new MessageItemType(MessageCollectionItemType.STRING), false); + /** */ + public TestMapMessageSerializer() { + } + /** */ @Override public boolean writeTo(TestMapMessage msg, MessageWriter writer) { if (!writer.isHeaderWritten()) { @@ -242,6 +248,12 @@ public class TestMapMessageSerializer implements MessageSerializer nested) throws IgniteCheckedException { + GridCacheContext ctx = nested; + + msg.marshal(marshaller); + } + + /** */ + @Override public void unmarshal(TestMarshallableMessage msg, GridKernalContext kctx, GridCacheContext nested) throws IgniteCheckedException { + GridCacheContext ctx = nested; + + msg.unmarshal(marshaller, clsLdr); + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMarshallableMessageMarshaller.java b/modules/core/src/test/resources/codegen/TestMarshallableMessageMarshaller.java new file mode 100644 index 0000000000000..5fd6f7cbd5954 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshallableMessageMarshaller.java @@ -0,0 +1,56 @@ +/* + * 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; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.TestMarshallableMessage; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMarshallableMessageMarshaller implements MessageMarshaller { + /** */ + private final Marshaller marshaller; + + /** */ + public TestMarshallableMessageMarshaller(Marshaller marshaller) { + this.marshaller = marshaller; + } + + /** */ + @Override public void marshal(TestMarshallableMessage msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException { + msg.marshal(marshaller); + } + + /** */ + @Override public void unmarshal(TestMarshallableMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + msg.unmarshal(marshaller, clsLdr); + } + + /** */ + @Override public void unmarshal(TestMarshallableMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + msg.unmarshal(marshaller, U.resolveClassLoader(kctx.config())); + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMarshallableMessageSerializer.java b/modules/core/src/test/resources/codegen/TestMarshallableMessageSerializer.java new file mode 100644 index 0000000000000..7216d8b30c604 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshallableMessageSerializer.java @@ -0,0 +1,97 @@ +/* + * 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; + +import org.apache.ignite.internal.TestMarshallableMessage; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMarshallableMessageSerializer implements MessageSerializer { + /** */ + public TestMarshallableMessageSerializer() { + } + + /** */ + @Override public boolean writeTo(TestMarshallableMessage msg, MessageWriter writer) { + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(msg.directType())) + return false; + + writer.onHeaderWritten(); + } + + switch (writer.state()) { + case 0: + if (!writer.writeInt(msg.iv)) + return false; + + writer.incrementState(); + + case 1: + if (!writer.writeString(msg.sv)) + return false; + + writer.incrementState(); + + case 2: + if (!writer.writeByteArray(msg.cstDataBytes)) + return false; + + writer.incrementState(); + } + + return true; + } + + /** */ + @Override public boolean readFrom(TestMarshallableMessage msg, MessageReader reader) { + switch (reader.state()) { + case 0: + msg.iv = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 1: + msg.sv = reader.readString(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 2: + msg.cstDataBytes = reader.readByteArray(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + } + + return true; + } +} diff --git a/modules/core/src/test/resources/codegen/TestMarshalledCollectionMessage.java b/modules/core/src/test/resources/codegen/TestMarshalledCollectionMessage.java new file mode 100644 index 0000000000000..61360b0d46142 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledCollectionMessage.java @@ -0,0 +1,34 @@ +/* + * 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; + +import java.util.Set; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.plugin.extensions.communication.Message; + +public class TestMarshalledCollectionMessage implements Message { + @MarshalledCollection("keysArr") + Set keys; + + @Order(0) + GridCacheVersion[] keysArr; + + public short directType() { + return 0; + } +} diff --git a/modules/core/src/test/resources/codegen/TestMarshalledCollectionMessageMarshaller.java b/modules/core/src/test/resources/codegen/TestMarshalledCollectionMessageMarshaller.java new file mode 100644 index 0000000000000..dd7c484948318 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledCollectionMessageMarshaller.java @@ -0,0 +1,80 @@ +/* + * 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; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.TestMarshalledCollectionMessage; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMarshalledCollectionMessageMarshaller implements MessageMarshaller { + /** */ + public TestMarshalledCollectionMessageMarshaller() { + } + + /** */ + @Override public void marshal(TestMarshalledCollectionMessage msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException { + CacheObjectContext ctx = nested; + + if (msg.keys != null && msg.keysArr == null) + msg.keysArr = msg.keys.toArray(new GridCacheVersion[0]); + + if (msg.keysArr != null) { + for (GridCacheVersion e : msg.keysArr) { + if (e != null) + MessageMarshaller.marshal(kctx.messageFactory(), e, kctx, ctx); + } + } + } + + /** */ + @Override public void unmarshal(TestMarshalledCollectionMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + CacheObjectContext ctx = nested; + + if (msg.keysArr != null) { + msg.keys = U.newHashSet(msg.keysArr.length); + + for (GridCacheVersion e : msg.keysArr) { + if (e != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), e, kctx, ctx, clsLdr); + + msg.keys.add(e); + } + + msg.keysArr = null; + } + } + + /** */ + @Override public void unmarshal(TestMarshalledCollectionMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + if (msg.keysArr != null) { + for (GridCacheVersion e : msg.keysArr) { + if (e != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), e, kctx); + } + } + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMarshalledCollectionMessageSerializer.java b/modules/core/src/test/resources/codegen/TestMarshalledCollectionMessageSerializer.java new file mode 100644 index 0000000000000..2ef81522ecc49 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledCollectionMessageSerializer.java @@ -0,0 +1,76 @@ +/* + * 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; + +import org.apache.ignite.internal.TestMarshalledCollectionMessage; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.plugin.extensions.communication.MessageArrayType; +import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; +import org.apache.ignite.plugin.extensions.communication.MessageItemType; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMarshalledCollectionMessageSerializer implements MessageSerializer { + /** */ + private static final MessageArrayType keysArrCollDesc = new MessageArrayType(new MessageItemType(MessageCollectionItemType.MSG), GridCacheVersion.class); + + /** */ + public TestMarshalledCollectionMessageSerializer() { + } + + /** */ + @Override public boolean writeTo(TestMarshalledCollectionMessage msg, MessageWriter writer) { + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(msg.directType())) + return false; + + writer.onHeaderWritten(); + } + + switch (writer.state()) { + case 0: + if (!writer.writeObjectArray(msg.keysArr, keysArrCollDesc)) + return false; + + writer.incrementState(); + } + + return true; + } + + /** */ + @Override public boolean readFrom(TestMarshalledCollectionMessage msg, MessageReader reader) { + switch (reader.state()) { + case 0: + msg.keysArr = reader.readObjectArray(keysArrCollDesc); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + } + + return true; + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMarshalledMapMessage.java b/modules/core/src/test/resources/codegen/TestMarshalledMapMessage.java new file mode 100644 index 0000000000000..e2a77b6fb2b43 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledMapMessage.java @@ -0,0 +1,38 @@ +/* + * 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; + +import java.util.Collection; +import java.util.Map; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.plugin.extensions.communication.Message; + +public class TestMarshalledMapMessage implements Message { + @MarshalledMap(keys = "mapKeys", values = "mapVals") + Map theMap; + + @Order(0) + Collection mapKeys; + + @Order(1) + Collection mapVals; + + public short directType() { + return 0; + } +} diff --git a/modules/core/src/test/resources/codegen/TestMarshalledMapMessageMarshaller.java b/modules/core/src/test/resources/codegen/TestMarshalledMapMessageMarshaller.java new file mode 100644 index 0000000000000..4c86a66302003 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledMapMessageMarshaller.java @@ -0,0 +1,108 @@ +/* + * 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; + +import java.util.Collection; +import java.util.Iterator; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.TestMarshalledMapMessage; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMarshalledMapMessageMarshaller implements MessageMarshaller { + /** */ + public TestMarshalledMapMessageMarshaller() { + } + + /** */ + @Override public void marshal(TestMarshalledMapMessage msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException { + CacheObjectContext ctx = nested; + + if (msg.theMap != null && msg.mapKeys == null) { + msg.mapKeys = msg.theMap.keySet(); + msg.mapVals = msg.theMap.values(); + } + + if (msg.mapKeys != null) { + for (GridCacheVersion e : (Collection)msg.mapKeys) { + if (e != null) + MessageMarshaller.marshal(kctx.messageFactory(), e, kctx, ctx); + } + } + + if (msg.mapVals != null) { + for (GridCacheVersion e : (Collection)msg.mapVals) { + if (e != null) + MessageMarshaller.marshal(kctx.messageFactory(), e, kctx, ctx); + } + } + } + + /** */ + @Override public void unmarshal(TestMarshalledMapMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + CacheObjectContext ctx = nested; + + if (msg.mapKeys != null) { + msg.theMap = U.newHashMap(msg.mapKeys.size()); + + Iterator keyIter = msg.mapKeys.iterator(); + Iterator valIter = msg.mapVals.iterator(); + + while (keyIter.hasNext()) { + GridCacheVersion k = keyIter.next(); + GridCacheVersion v = valIter.next(); + + if (k != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), k, kctx, ctx, clsLdr); + + if (v != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), v, kctx, ctx, clsLdr); + + msg.theMap.put(k, v); + } + + msg.mapKeys = null; + msg.mapVals = null; + } + } + + /** */ + @Override public void unmarshal(TestMarshalledMapMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + if (msg.mapKeys != null) { + for (GridCacheVersion e : (Collection)msg.mapKeys) { + if (e != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), e, kctx); + } + } + + if (msg.mapVals != null) { + for (GridCacheVersion e : (Collection)msg.mapVals) { + if (e != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), e, kctx); + } + } + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMarshalledMapMessageSerializer.java b/modules/core/src/test/resources/codegen/TestMarshalledMapMessageSerializer.java new file mode 100644 index 0000000000000..4b9b7e7432b90 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledMapMessageSerializer.java @@ -0,0 +1,91 @@ +/* + * 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; + +import org.apache.ignite.internal.TestMarshalledMapMessage; +import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; +import org.apache.ignite.plugin.extensions.communication.MessageCollectionType; +import org.apache.ignite.plugin.extensions.communication.MessageItemType; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMarshalledMapMessageSerializer implements MessageSerializer { + /** */ + private static final MessageCollectionType mapKeysCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.MSG), false); + /** */ + private static final MessageCollectionType mapValsCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.MSG), false); + + /** */ + public TestMarshalledMapMessageSerializer() { + } + + /** */ + @Override public boolean writeTo(TestMarshalledMapMessage msg, MessageWriter writer) { + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(msg.directType())) + return false; + + writer.onHeaderWritten(); + } + + switch (writer.state()) { + case 0: + if (!writer.writeCollection(msg.mapKeys, mapKeysCollDesc)) + return false; + + writer.incrementState(); + + case 1: + if (!writer.writeCollection(msg.mapVals, mapValsCollDesc)) + return false; + + writer.incrementState(); + } + + return true; + } + + /** */ + @Override public boolean readFrom(TestMarshalledMapMessage msg, MessageReader reader) { + switch (reader.state()) { + case 0: + msg.mapKeys = reader.readCollection(mapKeysCollDesc); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 1: + msg.mapVals = reader.readCollection(mapValsCollDesc); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + } + + return true; + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMarshalledMessage.java b/modules/core/src/test/resources/codegen/TestMarshalledMessage.java new file mode 100644 index 0000000000000..a110f5e9ecb59 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledMessage.java @@ -0,0 +1,32 @@ +/* + * 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; + +import org.apache.ignite.plugin.extensions.communication.Message; + +public class TestMarshalledMessage implements Message { + @Marshalled("dataBytes") + Object data; + + @Order(0) + byte[] dataBytes; + + public short directType() { + return 0; + } +} diff --git a/modules/core/src/test/resources/codegen/TestMarshalledMessageMarshaller.java b/modules/core/src/test/resources/codegen/TestMarshalledMessageMarshaller.java new file mode 100644 index 0000000000000..e43a98e37c372 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledMessageMarshaller.java @@ -0,0 +1,59 @@ +/* + * 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; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.TestMarshalledMessage; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMarshalledMessageMarshaller implements MessageMarshaller { + /** */ + private final Marshaller marshaller; + + /** */ + public TestMarshalledMessageMarshaller(Marshaller marshaller) { + this.marshaller = marshaller; + } + + /** */ + @Override public void marshal(TestMarshalledMessage msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException { + if (msg.data != null && msg.dataBytes == null) + msg.dataBytes = U.marshal(marshaller, msg.data); + } + + /** */ + @Override public void unmarshal(TestMarshalledMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + if (msg.dataBytes != null) + msg.data = U.unmarshal(marshaller, msg.dataBytes, clsLdr); + } + + /** */ + @Override public void unmarshal(TestMarshalledMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + if (msg.dataBytes != null) + msg.data = U.unmarshal(marshaller, msg.dataBytes, U.resolveClassLoader(kctx.config())); + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMarshalledMessageSerializer.java b/modules/core/src/test/resources/codegen/TestMarshalledMessageSerializer.java new file mode 100644 index 0000000000000..bcd6ec5ba8ee8 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledMessageSerializer.java @@ -0,0 +1,70 @@ +/* + * 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; + +import org.apache.ignite.internal.TestMarshalledMessage; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMarshalledMessageSerializer implements MessageSerializer { + /** */ + public TestMarshalledMessageSerializer() { + + } + + /** */ + @Override public boolean writeTo(TestMarshalledMessage msg, MessageWriter writer) { + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(msg.directType())) + return false; + + writer.onHeaderWritten(); + } + + switch (writer.state()) { + case 0: + if (!writer.writeByteArray(msg.dataBytes)) + return false; + + writer.incrementState(); + } + + return true; + } + + /** */ + @Override public boolean readFrom(TestMarshalledMessage msg, MessageReader reader) { + switch (reader.state()) { + case 0: + msg.dataBytes = reader.readByteArray(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + } + + return true; + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMarshalledObjectsMessage.java b/modules/core/src/test/resources/codegen/TestMarshalledObjectsMessage.java new file mode 100644 index 0000000000000..642fa34c70b30 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledObjectsMessage.java @@ -0,0 +1,33 @@ +/* + * 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; + +import java.util.Collection; +import org.apache.ignite.plugin.extensions.communication.Message; + +public class TestMarshalledObjectsMessage implements Message { + @Order(0) + Collection dataBytes; + + @MarshalledObjects("dataBytes") + Collection data; + + public short directType() { + return 0; + } +} diff --git a/modules/core/src/test/resources/codegen/TestMarshalledObjectsMessageMarshaller.java b/modules/core/src/test/resources/codegen/TestMarshalledObjectsMessageMarshaller.java new file mode 100644 index 0000000000000..42f9e58a47235 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledObjectsMessageMarshaller.java @@ -0,0 +1,70 @@ +/* + * 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; + +import java.util.ArrayList; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.TestMarshalledObjectsMessage; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMarshalledObjectsMessageMarshaller implements MessageMarshaller { + /** */ + private final Marshaller marshaller; + + /** */ + public TestMarshalledObjectsMessageMarshaller(Marshaller marshaller) { + this.marshaller = marshaller; + } + + /** */ + @Override public void marshal(TestMarshalledObjectsMessage msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException { + if (msg.data != null && msg.dataBytes == null) { + msg.dataBytes = new ArrayList<>(msg.data.size()); + + for (Object e : msg.data) + msg.dataBytes.add(U.marshal(marshaller, e)); + } + } + + /** */ + @Override public void unmarshal(TestMarshalledObjectsMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + CacheObjectContext ctx = nested; + + if (msg.dataBytes != null) { + msg.data = new ArrayList<>(msg.dataBytes.size()); + + for (byte[] e : msg.dataBytes) + msg.data.add(U.unmarshal(marshaller, e, clsLdr)); + + msg.dataBytes = null; + } + } + + /** */ + @Override public void unmarshal(TestMarshalledObjectsMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMarshalledObjectsMessageSerializer.java b/modules/core/src/test/resources/codegen/TestMarshalledObjectsMessageSerializer.java new file mode 100644 index 0000000000000..575c22eafb656 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMarshalledObjectsMessageSerializer.java @@ -0,0 +1,75 @@ +/* + * 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; + +import org.apache.ignite.internal.TestMarshalledObjectsMessage; +import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; +import org.apache.ignite.plugin.extensions.communication.MessageCollectionType; +import org.apache.ignite.plugin.extensions.communication.MessageItemType; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageSerializer; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMarshalledObjectsMessageSerializer implements MessageSerializer { + /** */ + private static final MessageCollectionType dataBytesCollDesc = new MessageCollectionType(new MessageItemType(MessageCollectionItemType.BYTE_ARR), false); + + /** */ + public TestMarshalledObjectsMessageSerializer() { + } + + /** */ + @Override public boolean writeTo(TestMarshalledObjectsMessage msg, MessageWriter writer) { + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(msg.directType())) + return false; + + writer.onHeaderWritten(); + } + + switch (writer.state()) { + case 0: + if (!writer.writeCollection(msg.dataBytes, dataBytesCollDesc)) + return false; + + writer.incrementState(); + } + + return true; + } + + /** */ + @Override public boolean readFrom(TestMarshalledObjectsMessage msg, MessageReader reader) { + switch (reader.state()) { + case 0: + msg.dataBytes = reader.readCollection(dataBytesCollDesc); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + } + + return true; + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMessage.java b/modules/core/src/test/resources/codegen/TestMessage.java index 6f3ef5eb1353a..5f8e5e7377743 100644 --- a/modules/core/src/test/resources/codegen/TestMessage.java +++ b/modules/core/src/test/resources/codegen/TestMessage.java @@ -44,12 +44,17 @@ public class TestMessage implements Message { @Order(4) int[][] intMatrix; + @NioField @Order(5) GridCacheVersion ver; @Order(6) GridCacheVersion[] verArr; + @NioField + @Order(15) + GridCacheVersion ver2; + @Order(7) UUID uuid; diff --git a/modules/core/src/test/resources/codegen/TestMessageMarshaller.java b/modules/core/src/test/resources/codegen/TestMessageMarshaller.java new file mode 100644 index 0000000000000..6cb8f05a7004e --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestMessageMarshaller.java @@ -0,0 +1,99 @@ +/* + * 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; + +import java.lang.String; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.TestMessage; +import org.apache.ignite.internal.processors.cache.CacheObjectContext; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestMessageMarshaller implements MessageMarshaller { + /** */ + public TestMessageMarshaller() { + } + + /** */ + @Override public void marshal(TestMessage msg, GridKernalContext kctx, CacheObjectContext nested) throws IgniteCheckedException { + CacheObjectContext ctx = nested; + + if (msg.ver != null) + MessageMarshaller.marshal(kctx.messageFactory(), msg.ver, kctx, ctx); + + if (msg.verArr != null) { + for (GridCacheVersion e : msg.verArr) { + if (e != null) + MessageMarshaller.marshal(kctx.messageFactory(), e, kctx, ctx); + } + } + + if (msg.keyCacheObject != null && ctx != null) + msg.keyCacheObject.marshal(ctx); + + if (msg.cacheObject != null && ctx != null) + msg.cacheObject.marshal(ctx); + + if (msg.ver2 != null) + MessageMarshaller.marshal(kctx.messageFactory(), msg.ver2, kctx, ctx); + } + + /** */ + @Override public void unmarshal(TestMessage msg, GridKernalContext kctx, CacheObjectContext nested, ClassLoader clsLdr) throws IgniteCheckedException { + CacheObjectContext ctx = nested; + + if (msg.verArr != null) { + for (GridCacheVersion e : msg.verArr) { + if (e != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), e, kctx, ctx, clsLdr); + } + } + + if (msg.keyCacheObject != null && ctx != null) + msg.keyCacheObject.unmarshal(ctx, clsLdr); + + if (msg.cacheObject != null && ctx != null) + msg.cacheObject.unmarshal(ctx, clsLdr); + } + + /** */ + @Override public void unmarshal(TestMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + if (msg.verArr != null) { + for (GridCacheVersion e : msg.verArr) { + if (e != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), e, kctx); + } + } + } + + /** */ + @Override public void unmarshalNio(TestMessage msg, GridKernalContext kctx) throws IgniteCheckedException { + if (msg.ver != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), msg.ver, kctx); + + if (msg.ver2 != null) + MessageMarshaller.unmarshal(kctx.messageFactory(), msg.ver2, kctx); + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestMessageSerializer.java b/modules/core/src/test/resources/codegen/TestMessageSerializer.java index 825928b57d327..ed406e78ff5ce 100644 --- a/modules/core/src/test/resources/codegen/TestMessageSerializer.java +++ b/modules/core/src/test/resources/codegen/TestMessageSerializer.java @@ -33,11 +33,15 @@ */ public class TestMessageSerializer implements MessageSerializer { /** */ - private final static MessageArrayType intMatrixCollDesc = new MessageArrayType(new MessageItemType(MessageCollectionItemType.INT_ARR), int[].class); + private static final MessageArrayType intMatrixCollDesc = new MessageArrayType(new MessageItemType(MessageCollectionItemType.INT_ARR), int[].class); /** */ - private final static MessageArrayType strArrCollDesc = new MessageArrayType(new MessageItemType(MessageCollectionItemType.STRING), String.class); + private static final MessageArrayType strArrCollDesc = new MessageArrayType(new MessageItemType(MessageCollectionItemType.STRING), String.class); /** */ - private final static MessageArrayType verArrCollDesc = new MessageArrayType(new MessageItemType(MessageCollectionItemType.MSG), GridCacheVersion.class); + private static final MessageArrayType verArrCollDesc = new MessageArrayType(new MessageItemType(MessageCollectionItemType.MSG), GridCacheVersion.class); + + /** */ + public TestMessageSerializer() { + } /** */ @Override public boolean writeTo(TestMessage msg, MessageWriter writer) { @@ -138,6 +142,12 @@ public class TestMessageSerializer implements MessageSerializer { return false; writer.incrementState(); + + case 15: + if (!writer.writeMessage(msg.ver2)) + return false; + + writer.incrementState(); } return true; @@ -261,6 +271,14 @@ public class TestMessageSerializer implements MessageSerializer { case 14: msg.gridLongList = reader.readGridLongList(); + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + msg.ver2 = reader.readMessage(); + if (!reader.isLastRead()) return false; diff --git a/modules/core/src/test/resources/codegen/TestNestedDeployMessage.java b/modules/core/src/test/resources/codegen/TestNestedDeployMessage.java new file mode 100644 index 0000000000000..2ce620f2b724a --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestNestedDeployMessage.java @@ -0,0 +1,33 @@ +/* + * 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; + +import org.apache.ignite.internal.processors.cache.GridCacheIdMessage; + +public class TestNestedDeployMessage extends GridCacheIdMessage { + @Order(0) + TestCacheIdMessage nested; + + public short directType() { + return 0; + } + + @Override public boolean addDeploymentInfo() { + return true; + } +} diff --git a/modules/core/src/test/resources/codegen/TestNestedDeployMessageDeployer.java b/modules/core/src/test/resources/codegen/TestNestedDeployMessageDeployer.java new file mode 100644 index 0000000000000..3f75e24b49d46 --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestNestedDeployMessageDeployer.java @@ -0,0 +1,35 @@ +/* + * 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; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.TestNestedDeployMessage; +import org.apache.ignite.internal.processors.cache.GridCacheMessageDeployer; +import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; + +/** + * This class is generated automatically. + * + * @see org.apache.ignite.internal.MessageProcessor + */ +public class TestNestedDeployMessageDeployer implements GridCacheMessageDeployer { + /** */ + @Override public void deploy(TestNestedDeployMessage msg, GridCacheSharedContext ctx) throws IgniteCheckedException { + GridCacheMessageDeployer.deploy(ctx.kernalContext().messageFactory(), msg.nested, ctx); + } +} \ No newline at end of file diff --git a/modules/core/src/test/resources/codegen/TestNoCacheCtxMessage.java b/modules/core/src/test/resources/codegen/TestNoCacheCtxMessage.java new file mode 100644 index 0000000000000..a9cb826dc8f8e --- /dev/null +++ b/modules/core/src/test/resources/codegen/TestNoCacheCtxMessage.java @@ -0,0 +1,34 @@ +/* + * 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; + +import org.apache.ignite.internal.processors.cache.CacheObject; +import org.apache.ignite.internal.processors.cache.GridCacheMessage; + +public class TestNoCacheCtxMessage extends GridCacheMessage { + @Order(0) + CacheObject val; + + public short directType() { + return 0; + } + + @Override public boolean addDeploymentInfo() { + return true; + } +} diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2CacheObject.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2CacheObject.java index 559f96bccad5c..92640ed4b75a4 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2CacheObject.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2CacheObject.java @@ -47,14 +47,14 @@ public GridH2CacheObject() { public GridH2CacheObject(GridH2ValueCacheObject v) throws IgniteCheckedException { obj = v.getCacheObject(); - obj.prepareMarshal(v.valueContext()); + obj.marshal(v.valueContext()); } /** {@inheritDoc} */ @Override public Value value(GridKernalContext ctx) throws IgniteCheckedException { CacheObjectValueContext valCtx = ctx.query().objectContext(); - obj.finishUnmarshal(valCtx, ctx.cache().context().deploy().globalLoader()); + obj.unmarshal(valCtx, ctx.cache().context().deploy().globalLoader()); return new GridH2ValueCacheObject(obj, valCtx); } diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2ValueMessage.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2ValueMessage.java index c24857ef13a17..6ebbfab981f9b 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2ValueMessage.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2ValueMessage.java @@ -19,13 +19,13 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.GridKernalContext; -import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.extensions.communication.NonMarshallableMessage; import org.h2.value.Value; /** * Abstract message wrapper for H2 values. */ -public abstract class GridH2ValueMessage implements Message { +public abstract class GridH2ValueMessage implements NonMarshallableMessage { /** * Gets H2 value. * diff --git a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/DiscoveryMessageParser.java b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/DiscoveryMessageParser.java index d29a73f7039f4..7e15d3c5ffbbd 100644 --- a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/DiscoveryMessageParser.java +++ b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/DiscoveryMessageParser.java @@ -25,12 +25,16 @@ import java.nio.ByteBuffer; import java.util.zip.DeflaterOutputStream; import java.util.zip.InflaterInputStream; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.direct.DirectMessageReader; import org.apache.ignite.internal.direct.DirectMessageWriter; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; +import org.apache.ignite.plugin.extensions.communication.MessageMarshaller; import org.apache.ignite.plugin.extensions.communication.MessageSerializer; import org.apache.ignite.spi.IgniteSpiException; +import org.apache.ignite.spi.discovery.zk.ZookeeperDiscoverySpi; import static org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi.makeMessageType; @@ -45,8 +49,15 @@ public class DiscoveryMessageParser { private final MessageFactory msgFactory; /** */ - public DiscoveryMessageParser(MessageFactory msgFactory) { + private final ZookeeperDiscoverySpi spi; + + /** + * @param msgFactory Message factory. + * @param spi Discovery SPI. + */ + public DiscoveryMessageParser(MessageFactory msgFactory, ZookeeperDiscoverySpi spi) { this.msgFactory = msgFactory; + this.spi = spi; } /** Marshals discovery message to bytes array. */ @@ -83,14 +94,19 @@ private void serializeMessage(Message m, OutputStream out) throws IOException { msgWriter.setBuffer(msgBuf); - MessageSerializer msgSer = msgFactory.serializer(m.directType()); + try { + MessageMarshaller.marshal(msgFactory, m, ((IgniteEx)spi.ignite()).context(), null); + } + catch (IgniteCheckedException e) { + throw new IgniteSpiException("Failed to marshal discovery message", e); + } boolean finished; do { msgBuf.clear(); - finished = msgSer.writeTo(m, msgWriter); + finished = MessageSerializer.writeTo(msgFactory, m, msgWriter); out.write(msgBuf.array(), 0, msgBuf.position()); } @@ -105,7 +121,6 @@ private T deserializeMessage(InputStream in) throws IOExcept msgReader.setBuffer(msgBuf); Message msg = msgFactory.create(makeMessageType((byte)in.read(), (byte)in.read())); - MessageSerializer msgSer = msgFactory.serializer(msg.directType()); boolean finished; @@ -117,7 +132,7 @@ private T deserializeMessage(InputStream in) throws IOExcept msgBuf.rewind(); } - finished = msgSer.readFrom(msg, msgReader); + finished = MessageSerializer.readFrom(msgFactory, msg, msgReader); assert read != -1 || finished : "Stream closed before message was fully read."; @@ -126,6 +141,13 @@ private T deserializeMessage(InputStream in) throws IOExcept } while (!finished); + try { + MessageMarshaller.unmarshal(msgFactory, msg, ((IgniteEx)spi.ignite()).context()); + } + catch (IgniteCheckedException e) { + throw new IgniteSpiException("Failed to unmarshal discovery message", e); + } + return (T)msg; } } diff --git a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkDiscoveryCustomEventData.java b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkDiscoveryCustomEventData.java index e606f384fcf0f..52161d34c8471 100644 --- a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkDiscoveryCustomEventData.java +++ b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkDiscoveryCustomEventData.java @@ -71,13 +71,13 @@ class ZkDiscoveryCustomEventData extends ZkDiscoveryEventData { } /** */ - public void prepareMarshal(DiscoveryMessageParser parser) { + public void marshal(DiscoveryMessageParser parser) { if (resolvedMsg != null) msgBytes = parser.marshalZip(resolvedMsg); } /** */ - public void finishUnmarshal(DiscoveryMessageParser parser) { + public void unmarshal(DiscoveryMessageParser parser) { if (msgBytes != null) resolvedMsg = parser.unmarshalZip(msgBytes); } diff --git a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkMessageFactory.java b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkMessageFactory.java index cf9f95a908f7e..d315981d993c2 100644 --- a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkMessageFactory.java +++ b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZkMessageFactory.java @@ -17,17 +17,19 @@ package org.apache.ignite.spi.discovery.zk.internal; +import org.apache.ignite.internal.plugin.AbstractMarshallableMessageFactoryProvider; import org.apache.ignite.plugin.extensions.communication.MessageFactory; -import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; /** */ -public class ZkMessageFactory implements MessageFactoryProvider { +public class ZkMessageFactory extends AbstractMarshallableMessageFactoryProvider { /** {@inheritDoc} */ @Override public void registerAll(MessageFactory factory) { - factory.register(400, ZkCommunicationErrorResolveFinishMessage::new, new ZkCommunicationErrorResolveFinishMessageSerializer()); - factory.register(401, ZkCommunicationErrorResolveStartMessage::new, new ZkCommunicationErrorResolveStartMessageSerializer()); - factory.register(402, ZkForceNodeFailMessage::new, new ZkForceNodeFailMessageSerializer()); - factory.register(403, ZkNoServersMessage::new, new ZkNoServersMessageSerializer()); - factory.register(404, ZkDiscoDataBagWrapper::new, new ZkDiscoDataBagWrapperSerializer()); + register(factory, ZkCommunicationErrorResolveFinishMessage.class, (short)400, + ZkCommunicationErrorResolveFinishMessage::new, dfltMarsh); + register(factory, ZkCommunicationErrorResolveStartMessage.class, (short)401, + ZkCommunicationErrorResolveStartMessage::new, dfltMarsh); + register(factory, ZkForceNodeFailMessage.class, (short)402, ZkForceNodeFailMessage::new, dfltMarsh); + register(factory, ZkNoServersMessage.class, (short)403, ZkNoServersMessage::new, dfltMarsh); + register(factory, ZkDiscoDataBagWrapper.class, (short)404, ZkDiscoDataBagWrapper::new, dfltMarsh); } } diff --git a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoveryImpl.java b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoveryImpl.java index f69e9f6d10658..a040e4b79018a 100644 --- a/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoveryImpl.java +++ b/modules/zookeeper/src/main/java/org/apache/ignite/spi/discovery/zk/internal/ZookeeperDiscoveryImpl.java @@ -271,7 +271,7 @@ public ZookeeperDiscoveryImpl( this.stats = stats; - msgParser = new DiscoveryMessageParser(msgFactory); + msgParser = new DiscoveryMessageParser(msgFactory, spi); } /** @@ -1490,7 +1490,7 @@ private void generateNoServersEvent(ZkDiscoveryEventsData evtsData, Stat evtsSta new ZkNoServersMessage(), null); - evtData.prepareMarshal(msgParser); + evtData.marshal(msgParser); Collection nodesToAck = Collections.emptyList(); @@ -1520,7 +1520,7 @@ private void previousCoordinatorCleanup(ZkDiscoveryEventsData lastEvts) throws E if (evtData instanceof ZkDiscoveryCustomEventData) { ZkDiscoveryCustomEventData evtData0 = (ZkDiscoveryCustomEventData)evtData; - evtData0.finishUnmarshal(msgParser); + evtData0.unmarshal(msgParser); // It is possible previous coordinator failed before finished cleanup. if (evtData0.resolvedMsg instanceof ZkCommunicationErrorResolveFinishMessage) { @@ -2750,7 +2750,7 @@ private void processNewEvents(final ZkDiscoveryEventsData evtsData) throws Excep if (evtData0.ackEvent() && evtData0.topologyVersion() < locNode.order()) break; - evtData0.finishUnmarshal(msgParser); + evtData0.unmarshal(msgParser); if (rtState.crd) assert evtData0.resolvedMsg != null : evtData0; @@ -3451,7 +3451,7 @@ private void onCommunicationErrorResolveStatusReceived(final ZkRuntimeState rtSt msg, null); - evtData.prepareMarshal(msgParser); + evtData.marshal(msgParser); evtsData.addEvent(rtState.top.nodesByOrder.values(), evtData); diff --git a/parent/pom.xml b/parent/pom.xml index 507e6d27edf36..3d0862e62d0d7 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -863,6 +863,7 @@ **/.asf.yaml .travis.yml .github/PULL_REQUEST_TEMPLATE.md + .mvn/jvm.config idea/ignite_codeStyle.xml **/DEVNOTES*.txt **/NOTICE*