|  | @@ -28,6 +28,7 @@ import org.elasticsearch.cluster.ESAllocationTestCase;
 | 
	
		
			
				|  |  |  import org.elasticsearch.cluster.RestoreInProgress;
 | 
	
		
			
				|  |  |  import org.elasticsearch.cluster.SnapshotDeletionsInProgress;
 | 
	
		
			
				|  |  |  import org.elasticsearch.cluster.metadata.IndexMetaData;
 | 
	
		
			
				|  |  | +import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
 | 
	
		
			
				|  |  |  import org.elasticsearch.cluster.metadata.MetaData;
 | 
	
		
			
				|  |  |  import org.elasticsearch.cluster.node.DiscoveryNodes;
 | 
	
		
			
				|  |  |  import org.elasticsearch.cluster.routing.RoutingTable;
 | 
	
	
		
			
				|  | @@ -43,6 +44,8 @@ import org.elasticsearch.snapshots.Snapshot;
 | 
	
		
			
				|  |  |  import org.elasticsearch.snapshots.SnapshotId;
 | 
	
		
			
				|  |  |  import org.elasticsearch.test.VersionUtils;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import java.io.IOException;
 | 
	
		
			
				|  |  | +import java.util.ArrayList;
 | 
	
		
			
				|  |  |  import java.util.Collections;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import static org.hamcrest.Matchers.equalTo;
 | 
	
	
		
			
				|  | @@ -154,4 +157,58 @@ public class ClusterSerializationTests extends ESAllocationTestCase {
 | 
	
		
			
				|  |  |          assertThat(stateAfterDiffs.custom(SnapshotDeletionsInProgress.TYPE), notNullValue());
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    private ClusterState updateUsingSerialisedDiff(ClusterState original, Diff<ClusterState> diff) throws IOException {
 | 
	
		
			
				|  |  | +        BytesStreamOutput outStream = new BytesStreamOutput();
 | 
	
		
			
				|  |  | +        outStream.setVersion(Version.CURRENT);
 | 
	
		
			
				|  |  | +        diff.writeTo(outStream);
 | 
	
		
			
				|  |  | +        StreamInput inStream = new NamedWriteableAwareStreamInput(outStream.bytes().streamInput(),
 | 
	
		
			
				|  |  | +            new NamedWriteableRegistry(ClusterModule.getNamedWriteables()));
 | 
	
		
			
				|  |  | +        diff = ClusterState.readDiffFrom(inStream, newNode("node-name"));
 | 
	
		
			
				|  |  | +        return diff.apply(original);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public void testObjectReuseWhenApplyingClusterStateDiff() throws Exception {
 | 
	
		
			
				|  |  | +        IndexMetaData indexMetaData
 | 
	
		
			
				|  |  | +            = IndexMetaData.builder("test").settings(settings(Version.CURRENT)).numberOfShards(10).numberOfReplicas(1).build();
 | 
	
		
			
				|  |  | +        IndexTemplateMetaData indexTemplateMetaData
 | 
	
		
			
				|  |  | +            = IndexTemplateMetaData.builder("test-template").patterns(new ArrayList<>()).build();
 | 
	
		
			
				|  |  | +        MetaData metaData = MetaData.builder().put(indexMetaData, true).put(indexTemplateMetaData).build();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        RoutingTable routingTable = RoutingTable.builder().addAsNew(metaData.index("test")).build();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        ClusterState clusterState1 = ClusterState.builder(new ClusterName("clusterName1"))
 | 
	
		
			
				|  |  | +            .metaData(metaData).routingTable(routingTable).build();
 | 
	
		
			
				|  |  | +        BytesStreamOutput outStream = new BytesStreamOutput();
 | 
	
		
			
				|  |  | +        outStream.setVersion(Version.CURRENT);
 | 
	
		
			
				|  |  | +        clusterState1.writeTo(outStream);
 | 
	
		
			
				|  |  | +        StreamInput inStream = new NamedWriteableAwareStreamInput(outStream.bytes().streamInput(),
 | 
	
		
			
				|  |  | +            new NamedWriteableRegistry(ClusterModule.getNamedWriteables()));
 | 
	
		
			
				|  |  | +        ClusterState serializedClusterState1 = ClusterState.readFrom(inStream, newNode("node4"));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // Create a new, albeit equal, IndexMetadata object
 | 
	
		
			
				|  |  | +        ClusterState clusterState2 = ClusterState.builder(clusterState1).incrementVersion()
 | 
	
		
			
				|  |  | +            .metaData(MetaData.builder().put(IndexMetaData.builder(indexMetaData).numberOfReplicas(1).build(), true)).build();
 | 
	
		
			
				|  |  | +        assertNotSame("Should have created a new, equivalent, IndexMetaData object in clusterState2",
 | 
	
		
			
				|  |  | +            clusterState1.metaData().index("test"), clusterState2.metaData().index("test"));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        ClusterState serializedClusterState2 = updateUsingSerialisedDiff(serializedClusterState1, clusterState2.diff(clusterState1));
 | 
	
		
			
				|  |  | +        assertSame("Unchanged metadata should not create new IndexMetaData objects",
 | 
	
		
			
				|  |  | +            serializedClusterState1.metaData().index("test"), serializedClusterState2.metaData().index("test"));
 | 
	
		
			
				|  |  | +        assertSame("Unchanged routing table should not create new IndexRoutingTable objects",
 | 
	
		
			
				|  |  | +            serializedClusterState1.routingTable().index("test"), serializedClusterState2.routingTable().index("test"));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // Create a new and different IndexMetadata object
 | 
	
		
			
				|  |  | +        ClusterState clusterState3 = ClusterState.builder(clusterState1).incrementVersion()
 | 
	
		
			
				|  |  | +            .metaData(MetaData.builder().put(IndexMetaData.builder(indexMetaData).numberOfReplicas(2).build(), true)).build();
 | 
	
		
			
				|  |  | +        ClusterState serializedClusterState3 = updateUsingSerialisedDiff(serializedClusterState2, clusterState3.diff(clusterState2));
 | 
	
		
			
				|  |  | +        assertNotEquals("Should have a new IndexMetaData object",
 | 
	
		
			
				|  |  | +            serializedClusterState2.metaData().index("test"), serializedClusterState3.metaData().index("test"));
 | 
	
		
			
				|  |  | +        assertSame("Unchanged routing table should not create new IndexRoutingTable objects",
 | 
	
		
			
				|  |  | +            serializedClusterState2.routingTable().index("test"), serializedClusterState3.routingTable().index("test"));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        assertSame("nodes", serializedClusterState2.nodes(), serializedClusterState3.nodes());
 | 
	
		
			
				|  |  | +        assertSame("blocks", serializedClusterState2.blocks(), serializedClusterState3.blocks());
 | 
	
		
			
				|  |  | +        assertSame("template", serializedClusterState2.metaData().templates().get("test-template"),
 | 
	
		
			
				|  |  | +            serializedClusterState3.metaData().templates().get("test-template"));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  }
 |