http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-portables.xml ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-portables.xml b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-portables.xml new file mode 100644 index 0000000..1d90c99 --- /dev/null +++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-portables.xml @@ -0,0 +1,226 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:util="http://www.springframework.org/schema/util" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/util + http://www.springframework.org/schema/util/spring-util.xsd"> + + <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> + <property name="localHost" value="127.0.0.1"/> + + <property name="marshaller"> + <bean class="org.gridgain.grid.marshaller.optimized.GridOptimizedMarshaller"> + <property name="requireSerializable" value="false"/> + </bean> + </property> + + <property name="includeEventTypes"> + <util:constant static-field="org.apache.ignite.events.IgniteEventType.EVTS_CACHE"/> + </property> + + <property name="portableConfiguration"> + <bean class="org.gridgain.grid.configuration.PortableConfiguration"> + <property name="typeConfigurations"> + <list> + <bean class="org.apache.ignite.portable.PortableTypeConfiguration"> + <property name="className" value="org.gridgain.client.GridClientTestPortable"/> + </bean> + <bean class="org.apache.ignite.portable.PortableTypeConfiguration"> + <property name="className" value="org.gridgain.client.model.PortablePerson"/> + </bean> + <bean class="org.apache.ignite.portable.PortableTypeConfiguration"> + <property name="className" value="org.gridgain.client.model.ImplicitPortablePerson"/> + </bean> + <bean class="org.apache.ignite.portable.PortableTypeConfiguration"> + <property name="className" value="NoDefPortablePerson"/> + </bean> + </list> + </property> + </bean> + </property> + + <property name="cacheConfiguration"> + <list> + <bean parent="cache-template"> + <property name="name" value="local"/> + <property name="cacheMode" value="LOCAL"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="local_atomic"/> + <property name="cacheMode" value="LOCAL"/> + <property name="atomicityMode" value="ATOMIC"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="partitioned"/> + <property name="cacheMode" value="PARTITIONED"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="partitioned_atomic"/> + <property name="cacheMode" value="PARTITIONED"/> + <property name="atomicityMode" value="ATOMIC"/> + <property name="atomicWriteOrderMode" value="PRIMARY"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="partitioned_near"/> + <property name="cacheMode" value="PARTITIONED"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + <property name="nearConfiguration"> + <bean class="org.apache.ignite.configuration.NearCacheConfiguration" /> + </property> + </bean> + + <bean parent="cache-template"> + <property name="name" value="partitioned_atomic_near"/> + <property name="cacheMode" value="PARTITIONED"/> + <property name="atomicityMode" value="ATOMIC"/> + <property name="atomicWriteOrderMode" value="PRIMARY"/> + <property name="nearConfiguration"> + <bean class="org.apache.ignite.configuration.NearCacheConfiguration" /> + </property> + </bean> + + <bean parent="cache-template"> + <property name="name" value="replicated"/> + <property name="cacheMode" value="REPLICATED"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="replicated_atomic"/> + <property name="cacheMode" value="REPLICATED"/> + <property name="atomicityMode" value="ATOMIC"/> + <property name="atomicWriteOrderMode" value="PRIMARY"/> + </bean> + </list> + </property> + + <property name="swapSpaceSpi"> + <bean class="org.gridgain.grid.spi.swapspace.inmemory.GridTestSwapSpaceSpi"/> + </property> + + <property name="indexingSpi"> + <list> + <bean class="org.gridgain.grid.spi.indexing.h2.GridH2IndexingSpi"> + </bean> + </list> + </property> + + <property name="discoverySpi"> + <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> + <property name="ipFinder"> + <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"> + <property name="addresses"> + <list> + <!-- In distributed environment, replace with actual host IP address. --> + <value>127.0.0.1:47500..47501</value> + </list> + </property> + </bean> + </property> + </bean> + </property> + + <property name="platformConfiguration"> + <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetConfiguration"> + <property name="portableConfiguration"> + <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetPortableConfiguration"> + <property name="types"> + <util:list value-type="java.lang.String"> + + </util:list> + </property> + </bean> + </property> + </bean> + </property> + </bean> + + <bean id="cache-template" abstract="true" class="org.apache.ignite.cache.CacheConfiguration"> + <property name="rebalanceMode" value="SYNC"/> + <property name="writeSynchronizationMode" value="FULL_SYNC"/> + <property name="swapEnabled" value="true"/> + <property name="portableEnabled" value="true"/> + <property name="txSerializableEnabled" value="true"/> + <property name="backups" value="1"/> + + <property name="store"> + <bean class="org.gridgain.grid.internal.processors.cache.GridCacheGenericTestStore"/> + </property> + + <property name="typeMetadata"> + <list> + <bean class="org.apache.ignite.cache.CacheTypeMetadata"> + <property name="valueType" value="PortablePerson"/> + <property name="ascendingFields"> + <map> + <entry key="age" value="java.lang.Integer"/> + </map> + </property> + <property name="queryFields"> + <map> + <entry key="name" value="java.lang.String"/> + </map> + </property> + <property name="textFields"> + <list> + <value>address</value> + </list> + </property> + </bean> + <bean class="org.apache.ignite.cache.CacheTypeMetadata"> + <property name="valueType" value="ImplicitPortablePerson"/> + <property name="ascendingFields"> + <map> + <entry key="age" value="java.lang.Integer"/> + </map> + </property> + <property name="queryFields"> + <map> + <entry key="name" value="java.lang.String"/> + </map> + </property> + </bean> + <bean class="org.apache.ignite.cache.CacheTypeMetadata"> + <property name="valueType" value="NoDefPortablePerson"/> + <property name="ascendingFields"> + <map> + <entry key="age" value="java.lang.Integer"/> + </map> + </property> + <property name="queryFields"> + <map> + <entry key="name" value="java.lang.String"/> + </map> + </property> + </bean> + </list> + </property> + </bean> +</beans>
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml new file mode 100644 index 0000000..9af4611 --- /dev/null +++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml @@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:util="http://www.springframework.org/schema/util" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/util + http://www.springframework.org/schema/util/spring-util.xsd"> + <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> + <property name="localHost" value="127.0.0.1"/> + <property name="connectorConfiguration"><null/></property> + + <property name="includeEventTypes"> + <util:constant static-field="org.apache.ignite.events.EventType.EVTS_CACHE"/> + </property> + + <property name="cacheConfiguration"> + <list> + <bean class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="portable_store"/> + <property name="cacheMode" value="LOCAL"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + <property name="writeThrough" value="true"/> + <property name="readThrough" value="true"/> + + <property name="cacheStoreFactory"> + <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactory"> + <property name="assemblyName" value="Apache.Ignite.Core.Tests"/> + <property name="className" value="Apache.Ignite.Core.Tests.Cache.Store.CacheTestStore"/> + </bean> + </property> + </bean> + + <bean class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="object_store"/> + <property name="cacheMode" value="LOCAL"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + <property name="writeThrough" value="true"/> + <property name="readThrough" value="true"/> + <property name="keepPortableInStore" value="false"/> + + <property name="cacheStoreFactory"> + <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactory"> + <property name="assemblyName" value="Apache.Ignite.Core.Tests"/> + <property name="className" value="Apache.Ignite.Core.Tests.Cache.Store.CacheTestStore"/> + </bean> + </property> + </bean> + + <bean class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="template_store*"/> + <property name="cacheMode" value="LOCAL"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + <property name="writeThrough" value="true"/> + <property name="readThrough" value="true"/> + <property name="keepPortableInStore" value="false"/> + + <property name="cacheStoreFactory"> + <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactory"> + <property name="assemblyName" value="Apache.Ignite.Core.Tests"/> + <property name="className" value="Apache.Ignite.Core.Tests.Cache.Store.CacheTestStore"/> + </bean> + </property> + </bean> + + <bean class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="custom_store"/> + <property name="cacheMode" value="LOCAL"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + <property name="writeThrough" value="true"/> + <property name="readThrough" value="true"/> + + <property name="cacheStoreFactory"> + <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactory"> + <property name="assemblyName" value="Apache.Ignite.Core.Tests"/> + <property name="className" value="Apache.Ignite.Core.Tests.Cache.Store.CacheTestStore"/> + <property name="properties"> + <map> + <entry key="IntProperty"> + <value type="java.lang.Integer">42</value> + </entry> + <entry key="StringProperty" value="String value"/> + </map> + </property> + </bean> + </property> + </bean> + </list> + </property> + + <property name="discoverySpi"> + <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> + <property name="ipFinder"> + <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"> + <property name="addresses"> + <list> + <!-- In distributed environment, replace with actual host IP address. --> + <value>127.0.0.1:47500..47501</value> + </list> + </property> + </bean> + </property> + </bean> + </property> + </bean> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache.xml ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache.xml b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache.xml new file mode 100644 index 0000000..5d65ae8 --- /dev/null +++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache.xml @@ -0,0 +1,224 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:util="http://www.springframework.org/schema/util" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/util + http://www.springframework.org/schema/util/spring-util.xsd"> + <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> + <property name="localHost" value="127.0.0.1"/> + <property name="connectorConfiguration"><null/></property> + + <property name="marshaller"> + <bean class="org.apache.ignite.marshaller.portable.PortableMarshaller"> + <property name="typeConfigurations"> + <list> + <bean class="org.apache.ignite.portable.PortableTypeConfiguration"> + <property name="className" value="org.gridgain.client.ClientTestPortable"/> + </bean> + <bean class="org.apache.ignite.portable.PortableTypeConfiguration"> + <property name="className" value="org.gridgain.internal.client.model.PortablePerson"/> + </bean> + <bean class="org.apache.ignite.portable.PortableTypeConfiguration"> + <property name="className" value="org.gridgain.internal.client.model.ImplicitPortablePerson"/> + </bean> + <bean class="org.apache.ignite.portable.PortableTypeConfiguration"> + <property name="className" value="NoDefPortablePerson"/> + </bean> + </list> + </property> + </bean> + </property> + + <property name="includeEventTypes"> + <util:constant static-field="org.apache.ignite.events.EventType.EVTS_CACHE"/> + </property> + + <property name="cacheConfiguration"> + <list> + <bean parent="cache-template"> + <property name="name" value="local"/> + <property name="cacheMode" value="LOCAL"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + <property name="startSize" value="10"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="local_atomic"/> + <property name="cacheMode" value="LOCAL"/> + <property name="atomicityMode" value="ATOMIC"/> + <property name="startSize" value="10"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="partitioned"/> + <property name="cacheMode" value="PARTITIONED"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + <property name="startSize" value="10"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="partitioned_atomic"/> + <property name="cacheMode" value="PARTITIONED"/> + <property name="atomicityMode" value="ATOMIC"/> + <property name="atomicWriteOrderMode" value="PRIMARY"/> + <property name="startSize" value="10"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="partitioned_near"/> + <property name="cacheMode" value="PARTITIONED"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + <property name="nearConfiguration"> + <bean class="org.apache.ignite.configuration.NearCacheConfiguration" /> + </property> + <property name="startSize" value="10"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="partitioned_atomic_near"/> + <property name="cacheMode" value="PARTITIONED"/> + <property name="atomicityMode" value="ATOMIC"/> + <property name="atomicWriteOrderMode" value="PRIMARY"/> + <property name="nearConfiguration"> + <bean class="org.apache.ignite.configuration.NearCacheConfiguration" /> + </property> + <property name="startSize" value="10"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="replicated"/> + <property name="cacheMode" value="REPLICATED"/> + <property name="atomicityMode" value="TRANSACTIONAL"/> + <property name="startSize" value="10"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="replicated_atomic"/> + <property name="cacheMode" value="REPLICATED"/> + <property name="atomicityMode" value="ATOMIC"/> + <property name="atomicWriteOrderMode" value="PRIMARY"/> + <property name="startSize" value="10"/> + </bean> + + <bean parent="cache-template"> + <property name="name" value="template*"/> + <property name="startSize" value="10"/> + </bean> + </list> + </property> + + <property name="swapSpaceSpi"> + <bean class="org.apache.ignite.spi.swapspace.inmemory.GridTestSwapSpaceSpi"/> + </property> + + <!-- TODO: --> + <!--<property name="indexingSpi"> + <list> + <bean class="org.gridgain.grid.spi.indexing.h2.GridH2IndexingSpi"> + <property name="defaultIndexFixedTyping" value="false"/> + </bean> + </list> + </property>--> + + <property name="discoverySpi"> + <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> + <property name="ipFinder"> + <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"> + <property name="addresses"> + <list> + <!-- In distributed environment, replace with actual host IP address. --> + <value>127.0.0.1:47500..47501</value> + </list> + </property> + </bean> + </property> + </bean> + </property> + + <property name="transactionConfiguration"> + <bean class="org.apache.ignite.configuration.TransactionConfiguration"> + <property name="txSerializableEnabled" value="true"/> + </bean> + </property> + </bean> + + <bean id="cache-template" abstract="true" class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="rebalanceMode" value="SYNC"/> + <property name="writeSynchronizationMode" value="FULL_SYNC"/> + <property name="swapEnabled" value="true"/> + <property name="backups" value="1"/> + <property name="eagerTtl" value="true"/> + + <!-- + <property name="typeMetadata"> + <list> + <bean class="org.apache.ignite.cache.CacheTypeMetadata"> + <property name="valueType" value="GridPortablePerson"/> + <property name="ascendingFields"> + <map> + <entry key="age" value="java.lang.Integer"/> + </map> + </property> + <property name="queryFields"> + <map> + <entry key="name" value="java.lang.String"/> + </map> + </property> + <property name="textFields"> + <list> + <value>address</value> + </list> + </property> + </bean> + <bean class="org.apache.ignite.cache.CacheTypeMetadata"> + <property name="valueType" value="GridImplicitPortablePerson"/> + <property name="ascendingFields"> + <map> + <entry key="age" value="java.lang.Integer"/> + </map> + </property> + <property name="queryFields"> + <map> + <entry key="name" value="java.lang.String"/> + </map> + </property> + </bean> + <bean class="org.apache.ignite.cache.CacheTypeMetadata"> + <property name="valueType" value="GridNoDefPortablePerson"/> + <property name="ascendingFields"> + <map> + <entry key="age" value="java.lang.Integer"/> + </map> + </property> + <property name="queryFields"> + <map> + <entry key="name" value="java.lang.String"/> + </map> + </property> + </bean> + </list> + </property> + --> + </bean> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/portable.xml ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/portable.xml b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/portable.xml new file mode 100644 index 0000000..f013749 --- /dev/null +++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/portable.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> + <property name="localHost" value="127.0.0.1"/> + <property name="connectorConfiguration"><null/></property> + + <property name="gridName" value="grid"/> + + <property name="metricsUpdateFrequency" value="1000"/> + <property name="metricsLogFrequency" value="0"/> + + <property name="cacheConfiguration"> + <list> + <bean class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="cache"/> + </bean> + </list> + </property> + + <property name="discoverySpi"> + <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> + <property name="ipFinder"> + <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"> + <property name="addresses"> + <list> + <!-- In distributed environment, replace with actual host IP address. --> + <value>127.0.0.1:47500..47502</value> + </list> + </property> + </bean> + </property> + </bean> + </property> + </bean> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid1.xml ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid1.xml b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid1.xml new file mode 100644 index 0000000..8559173 --- /dev/null +++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid1.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> + <property name="localHost" value="127.0.0.1"/> + <property name="connectorConfiguration"><null/></property> + + <property name="gridName" value="grid1"/> + + <property name="cacheConfiguration"> + <list> + <bean class="org.apache.ignite.configuration.CacheConfiguration"> + <property name="name" value="cache1"/> + <property name="rebalanceMode" value="SYNC"/> + </bean> + </list> + </property> + + <property name="discoverySpi"> + <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> + <property name="ipFinder"> + <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"> + <property name="addresses"> + <list> + <!-- In distributed environment, replace with actual host IP address. --> + <value>127.0.0.1:47500..47502</value> + </list> + </property> + </bean> + </property> + </bean> + </property> + </bean> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid2.xml ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid2.xml b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid2.xml new file mode 100644 index 0000000..cb628fe --- /dev/null +++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid2.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> + <property name="localHost" value="127.0.0.1"/> + <property name="connectorConfiguration"><null/></property> + + <property name="gridName" value="grid2"/> + + <property name="discoverySpi"> + <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> + <property name="ipFinder"> + <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"> + <property name="addresses"> + <list> + <!-- In distributed environment, replace with actual host IP address. --> + <value>127.0.0.1:47500..47502</value> + </list> + </property> + </bean> + </property> + </bean> + </property> + </bean> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid3.xml ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid3.xml b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid3.xml new file mode 100644 index 0000000..753fad1 --- /dev/null +++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid3.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> + <property name="localHost" value="127.0.0.1"/> + <property name="connectorConfiguration"><null/></property> + + <property name="discoverySpi"> + <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> + <property name="ipFinder"> + <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"> + <property name="addresses"> + <list> + <!-- In distributed environment, replace with actual host IP address. --> + <value>127.0.0.1:47500..47502</value> + </list> + </property> + </bean> + </property> + </bean> + </property> + </bean> +</beans> http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs ---------------------------------------------------------------------- diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs new file mode 100644 index 0000000..3c1619b --- /dev/null +++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs @@ -0,0 +1,592 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Tests.Dataload +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + using System.Threading; + using Apache.Ignite.Core.Cache; + using Apache.Ignite.Core.Datastream; + using Apache.Ignite.Core.Impl; + using Apache.Ignite.Core.Portable; + using Apache.Ignite.Core.Tests.Cache; + using NUnit.Framework; + + /// <summary> + /// Data streamer tests. + /// </summary> + public class DataStreamerTest + { + /** Node name. */ + protected const string GridName = "grid"; + + /** Cache name. */ + protected const string CacheName = "partitioned"; + + /** Node. */ + private IIgnite _grid; + + /** Cache. */ + private ICache<int, int?> _cache; + + /// <summary> + /// Initialization routine. + /// </summary> + [TestFixtureSetUp] + public virtual void InitClient() + { + _grid = Ignition.Start(GetIgniteConfiguration(GridName)); + + Ignition.Start(GetIgniteConfiguration(GridName + "_1")); + + _cache = _grid.Cache<int, int?>(CacheName); + } + + /// <summary> + /// + /// </summary> + [TestFixtureTearDown] + public virtual void StopGrids() + { + Ignition.StopAll(true); + } + + /// <summary> + /// + /// </summary> + [SetUp] + public virtual void BeforeTest() + { + Console.WriteLine("Test started: " + TestContext.CurrentContext.Test.Name); + + for (int i = 0; i < 100; i++) + _cache.Remove(i); + } + + [TearDown] + public void AfterTest() + { + TestUtils.AssertHandleRegistryIsEmpty(_grid, 1000); + } + + /// <summary> + /// Test data streamer property configuration. Ensures that at least no exceptions are thrown. + /// </summary> + [Test] + public void TestPropertyPropagation() + { + using (IDataStreamer<int, int> ldr = _grid.DataStreamer<int, int>(CacheName)) + { + ldr.AllowOverwrite = true; + Assert.IsTrue(ldr.AllowOverwrite); + ldr.AllowOverwrite = false; + Assert.IsFalse(ldr.AllowOverwrite); + + ldr.SkipStore = true; + Assert.IsTrue(ldr.SkipStore); + ldr.SkipStore = false; + Assert.IsFalse(ldr.SkipStore); + + ldr.PerNodeBufferSize = 1; + Assert.AreEqual(1, ldr.PerNodeBufferSize); + ldr.PerNodeBufferSize = 2; + Assert.AreEqual(2, ldr.PerNodeBufferSize); + + ldr.PerNodeParallelOperations = 1; + Assert.AreEqual(1, ldr.PerNodeParallelOperations); + ldr.PerNodeParallelOperations = 2; + Assert.AreEqual(2, ldr.PerNodeParallelOperations); + } + } + + /// <summary> + /// Test data add/remove. + /// </summary> + [Test] + public void TestAddRemove() + { + using (IDataStreamer<int, int> ldr = _grid.DataStreamer<int, int>(CacheName)) + { + ldr.AllowOverwrite = true; + + // Additions. + ldr.AddData(1, 1); + ldr.Flush(); + Assert.AreEqual(1, _cache.Get(1)); + + ldr.AddData(new KeyValuePair<int, int>(2, 2)); + ldr.Flush(); + Assert.AreEqual(2, _cache.Get(2)); + + ldr.AddData(new List<KeyValuePair<int, int>> { new KeyValuePair<int, int>(3, 3), new KeyValuePair<int, int>(4, 4) }); + ldr.Flush(); + Assert.AreEqual(3, _cache.Get(3)); + Assert.AreEqual(4, _cache.Get(4)); + + // Removal. + ldr.RemoveData(1); + ldr.Flush(); + Assert.IsNull(_cache.Get(1)); + + // Mixed. + ldr.AddData(5, 5); + ldr.RemoveData(2); + ldr.AddData(new KeyValuePair<int, int>(7, 7)); + ldr.AddData(6, 6); + ldr.RemoveData(4); + ldr.AddData(new List<KeyValuePair<int, int>> { new KeyValuePair<int, int>(9, 9), new KeyValuePair<int, int>(10, 10) }); + ldr.AddData(new KeyValuePair<int, int>(8, 8)); + ldr.RemoveData(3); + ldr.AddData(new List<KeyValuePair<int, int>> { new KeyValuePair<int, int>(11, 11), new KeyValuePair<int, int>(12, 12) }); + + ldr.Flush(); + + for (int i = 2; i < 5; i++) + Assert.IsNull(_cache.Get(i)); + + for (int i = 5; i < 13; i++) + Assert.AreEqual(i, _cache.Get(i)); + } + } + + /// <summary> + /// Test "tryFlush". + /// </summary> + [Test] + public void TestTryFlush() + { + using (IDataStreamer<int, int> ldr = _grid.DataStreamer<int, int>(CacheName)) + { + var fut = ldr.AddData(1, 1); + + ldr.TryFlush(); + + fut.Get(); + + Assert.AreEqual(1, _cache.Get(1)); + } + } + + /// <summary> + /// Test buffer size adjustments. + /// </summary> + [Test] + public void TestBufferSize() + { + using (IDataStreamer<int, int> ldr = _grid.DataStreamer<int, int>(CacheName)) + { + var fut = ldr.AddData(1, 1); + + Thread.Sleep(100); + + Assert.IsFalse(fut.IsDone); + + ldr.PerNodeBufferSize = 2; + + ldr.AddData(2, 2); + ldr.AddData(3, 3); + ldr.AddData(4, 4).Get(); + fut.Get(); + + Assert.AreEqual(1, _cache.Get(1)); + Assert.AreEqual(2, _cache.Get(2)); + Assert.AreEqual(3, _cache.Get(3)); + Assert.AreEqual(4, _cache.Get(4)); + + ldr.AddData(new List<KeyValuePair<int, int>> + { + new KeyValuePair<int, int>(5, 5), + new KeyValuePair<int, int>(6, 6), + new KeyValuePair<int, int>(7, 7), + new KeyValuePair<int, int>(8, 8) + }).Get(); + + Assert.AreEqual(5, _cache.Get(5)); + Assert.AreEqual(6, _cache.Get(6)); + Assert.AreEqual(7, _cache.Get(7)); + Assert.AreEqual(8, _cache.Get(8)); + } + } + + /// <summary> + /// Test close. + /// </summary> + [Test] + public void TestClose() + { + using (IDataStreamer<int, int> ldr = _grid.DataStreamer<int, int>(CacheName)) + { + var fut = ldr.AddData(1, 1); + + ldr.Close(false); + + fut.Get(); + + Assert.AreEqual(1, _cache.Get(1)); + } + } + + /// <summary> + /// Test close with cancellation. + /// </summary> + [Test] + public void TestCancel() + { + using (IDataStreamer<int, int> ldr = _grid.DataStreamer<int, int>(CacheName)) + { + var fut = ldr.AddData(1, 1); + + ldr.Close(true); + + fut.Get(); + + Assert.IsNull(_cache.Get(1)); + } + } + + /// <summary> + /// Tests that streamer gets collected when there are no references to it. + /// </summary> + [Test] + public void TestFinalizer() + { + var streamer = _grid.DataStreamer<int, int>(CacheName); + var streamerRef = new WeakReference(streamer); + + Assert.IsNotNull(streamerRef.Target); + + // ReSharper disable once RedundantAssignment + streamer = null; + + GC.Collect(); + GC.WaitForPendingFinalizers(); + + Assert.IsNull(streamerRef.Target); + } + + /// <summary> + /// Test auto-flush feature. + /// </summary> + [Test] + public void TestAutoFlush() + { + using (IDataStreamer<int, int> ldr = _grid.DataStreamer<int, int>(CacheName)) + { + // Test auto flush turning on. + var fut = ldr.AddData(1, 1); + Thread.Sleep(100); + Assert.IsFalse(fut.IsDone); + ldr.AutoFlushFrequency = 1000; + fut.Get(); + + // Test forced flush after frequency change. + fut = ldr.AddData(2, 2); + ldr.AutoFlushFrequency = long.MaxValue; + fut.Get(); + + // Test another forced flush after frequency change. + fut = ldr.AddData(3, 3); + ldr.AutoFlushFrequency = 1000; + fut.Get(); + + // Test flush before stop. + fut = ldr.AddData(4, 4); + ldr.AutoFlushFrequency = 0; + fut.Get(); + + // Test flush after second turn on. + fut = ldr.AddData(5, 5); + ldr.AutoFlushFrequency = 1000; + fut.Get(); + + Assert.AreEqual(1, _cache.Get(1)); + Assert.AreEqual(2, _cache.Get(2)); + Assert.AreEqual(3, _cache.Get(3)); + Assert.AreEqual(4, _cache.Get(4)); + Assert.AreEqual(5, _cache.Get(5)); + } + } + + /// <summary> + /// Test multithreaded behavior. + /// </summary> + [Test] + [Category(TestUtils.CategoryIntensive)] + public void TestMultithreaded() + { + int entriesPerThread = 100000; + int threadCnt = 8; + + for (int i = 0; i < 5; i++) + { + _cache.Clear(); + + Assert.AreEqual(0, _cache.Size()); + + Stopwatch watch = new Stopwatch(); + + watch.Start(); + + using (IDataStreamer<int, int> ldr = _grid.DataStreamer<int, int>(CacheName)) + { + ldr.PerNodeBufferSize = 1024; + + int ctr = 0; + + TestUtils.RunMultiThreaded(() => + { + int threadIdx = Interlocked.Increment(ref ctr); + + int startIdx = (threadIdx - 1) * entriesPerThread; + int endIdx = startIdx + entriesPerThread; + + for (int j = startIdx; j < endIdx; j++) + { + // ReSharper disable once AccessToDisposedClosure + ldr.AddData(j, j); + + if (j % 100000 == 0) + Console.WriteLine("Put [thread=" + threadIdx + ", cnt=" + j + ']'); + } + }, threadCnt); + } + + Console.WriteLine("Iteration " + i + ": " + watch.ElapsedMilliseconds); + + watch.Reset(); + + for (int j = 0; j < threadCnt * entriesPerThread; j++) + Assert.AreEqual(j, j); + } + } + + /// <summary> + /// Tests custom receiver. + /// </summary> + [Test] + public void TestStreamReceiver() + { + TestStreamReceiver(new StreamReceiverPortable()); + TestStreamReceiver(new StreamReceiverSerializable()); + } + + /// <summary> + /// Tests StreamVisitor. + /// </summary> + [Test] + public void TestStreamVisitor() + { + TestStreamReceiver(new StreamVisitor<int, int>((c, e) => c.Put(e.Key, e.Value + 1))); + } + + /// <summary> + /// Tests StreamTransformer. + /// </summary> + [Test] + public void TestStreamTransformer() + { + TestStreamReceiver(new StreamTransformer<int, int, int, int>(new EntryProcessorSerializable())); + TestStreamReceiver(new StreamTransformer<int, int, int, int>(new EntryProcessorPortable())); + } + + /// <summary> + /// Tests specified receiver. + /// </summary> + private void TestStreamReceiver(IStreamReceiver<int, int> receiver) + { + using (var ldr = _grid.DataStreamer<int, int>(CacheName)) + { + ldr.AllowOverwrite = true; + + ldr.Receiver = new StreamReceiverPortable(); + + ldr.Receiver = receiver; // check double assignment + + Assert.AreEqual(ldr.Receiver, receiver); + + for (var i = 0; i < 100; i++) + ldr.AddData(i, i); + + ldr.Flush(); + + for (var i = 0; i < 100; i++) + Assert.AreEqual(i + 1, _cache.Get(i)); + } + } + + /// <summary> + /// Tests the stream receiver in keepPortable mode. + /// </summary> + [Test] + public void TestStreamReceiverKeepPortable() + { + // ReSharper disable once LocalVariableHidesMember + var cache = _grid.Cache<int, PortableEntry>(CacheName); + + using (var ldr0 = _grid.DataStreamer<int, int>(CacheName)) + using (var ldr = ldr0.WithKeepPortable<int, IPortableObject>()) + { + ldr.Receiver = new StreamReceiverKeepPortable(); + + ldr.AllowOverwrite = true; + + for (var i = 0; i < 100; i++) + ldr.AddData(i, _grid.Portables().ToPortable<IPortableObject>(new PortableEntry {Val = i})); + + ldr.Flush(); + + for (var i = 0; i < 100; i++) + Assert.AreEqual(i + 1, cache.Get(i).Val); + } + } + + /// <summary> + /// Gets the Ignite configuration. + /// </summary> + /// <param name="gridName">Grid name.</param> + private static IgniteConfigurationEx GetIgniteConfiguration(string gridName) + { + return new IgniteConfigurationEx + { + GridName = gridName, + SpringConfigUrl = "config\\native-client-test-cache.xml", + JvmClasspath = TestUtils.CreateTestClasspath(), + PortableConfiguration = new PortableConfiguration + { + TypeConfigurations = new List<PortableTypeConfiguration> + { + new PortableTypeConfiguration(typeof (CacheTestKey)), + new PortableTypeConfiguration(typeof (TestReferenceObject)), + new PortableTypeConfiguration(typeof (StreamReceiverPortable)), + new PortableTypeConfiguration(typeof (EntryProcessorPortable)), + new PortableTypeConfiguration(typeof (PortableEntry)) + } + }, + JvmOptions = TestUtils.TestJavaOptions().Concat(new[] + { + "-Xms3096m", + "-Xmx3096m", + "-XX:+UseParNewGC", + "-XX:+UseConcMarkSweepGC", + "-XX:+UseTLAB", + "-XX:NewSize=128m", + "-XX:MaxNewSize=128m", + "-XX:MaxTenuringThreshold=0", + "-XX:SurvivorRatio=1024", + "-XX:+UseCMSInitiatingOccupancyOnly", + "-XX:CMSInitiatingOccupancyFraction=60" + }).ToArray() + }; + } + + /// <summary> + /// Test portable receiver. + /// </summary> + private class StreamReceiverPortable : IStreamReceiver<int, int> + { + /** <inheritdoc /> */ + public void Receive(ICache<int, int> cache, ICollection<ICacheEntry<int, int>> entries) + { + cache.PutAll(entries.ToDictionary(x => x.Key, x => x.Value + 1)); + } + } + + /// <summary> + /// Test portable receiver. + /// </summary> + [Serializable] + private class StreamReceiverKeepPortable : IStreamReceiver<int, IPortableObject> + { + /** <inheritdoc /> */ + public void Receive(ICache<int, IPortableObject> cache, ICollection<ICacheEntry<int, IPortableObject>> entries) + { + var portables = cache.Ignite.Portables(); + + cache.PutAll(entries.ToDictionary(x => x.Key, x => + portables.ToPortable<IPortableObject>(new PortableEntry + { + Val = x.Value.Deserialize<PortableEntry>().Val + 1 + }))); + } + } + + /// <summary> + /// Test serializable receiver. + /// </summary> + [Serializable] + private class StreamReceiverSerializable : IStreamReceiver<int, int> + { + /** <inheritdoc /> */ + public void Receive(ICache<int, int> cache, ICollection<ICacheEntry<int, int>> entries) + { + cache.PutAll(entries.ToDictionary(x => x.Key, x => x.Value + 1)); + } + } + + /// <summary> + /// Test entry processor. + /// </summary> + [Serializable] + private class EntryProcessorSerializable : ICacheEntryProcessor<int, int, int, int> + { + /** <inheritdoc /> */ + public int Process(IMutableCacheEntry<int, int> entry, int arg) + { + entry.Value = entry.Key + 1; + + return 0; + } + } + + /// <summary> + /// Test entry processor. + /// </summary> + private class EntryProcessorPortable : ICacheEntryProcessor<int, int, int, int>, IPortableMarshalAware + { + /** <inheritdoc /> */ + public int Process(IMutableCacheEntry<int, int> entry, int arg) + { + entry.Value = entry.Key + 1; + + return 0; + } + + /** <inheritdoc /> */ + public void WritePortable(IPortableWriter writer) + { + // No-op. + } + + /** <inheritdoc /> */ + public void ReadPortable(IPortableReader reader) + { + // No-op. + } + } + + /// <summary> + /// Portablecache entry. + /// </summary> + private class PortableEntry + { + public int Val { get; set; } + } + } +}
