Skip to content

Commit 969a053

Browse files
committed
Move Streams.copy into elasticsearch-core and make a multi-release jar
This moves the method `Streams.copy(InputStream in, OutputStream out)` into the `elasticsearch-core` project (inside the `o.e.core.internal.io` package). It also makes this class into a multi-release class where the Java 9 equivalent uses `InputStream#transferTo`. This is a followup from #29300 (comment)
1 parent 199d131 commit 969a053

File tree

17 files changed

+211
-43
lines changed

17 files changed

+211
-43
lines changed

libs/elasticsearch-core/build.gradle

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,29 @@ forbiddenApisMain {
5252
signaturesURLs = [PrecommitTasks.getResource('/forbidden/jdk-signatures.txt')]
5353
}
5454

55+
// we want to keep the JDKs in our IDEs set to JDK 8 until minimum JDK is bumped to 9 so we do not include this source set in our IDEs
56+
if (!isEclipse && !isIdea) {
57+
sourceSets {
58+
java9 {
59+
java {
60+
srcDirs = ['src/main/java9']
61+
}
62+
}
63+
}
64+
65+
compileJava9Java {
66+
sourceCompatibility = 9
67+
targetCompatibility = 9
68+
}
69+
70+
jar {
71+
into('META-INF/versions/9') {
72+
from sourceSets.java9.output
73+
}
74+
manifest.attributes('Multi-Release': 'true')
75+
}
76+
}
77+
5578
if (isEclipse) {
5679
// in eclipse the project is under a fake root, we need to change around the source sets
5780
sourceSets {
@@ -66,14 +89,14 @@ if (isEclipse) {
6689
}
6790

6891
thirdPartyAudit.excludes = [
69-
// from log4j
70-
'org/osgi/framework/AdaptPermission',
71-
'org/osgi/framework/AdminPermission',
72-
'org/osgi/framework/Bundle',
73-
'org/osgi/framework/BundleActivator',
74-
'org/osgi/framework/BundleContext',
75-
'org/osgi/framework/BundleEvent',
76-
'org/osgi/framework/SynchronousBundleListener',
77-
'org/osgi/framework/wiring/BundleWire',
78-
'org/osgi/framework/wiring/BundleWiring'
92+
// from log4j
93+
'org/osgi/framework/AdaptPermission',
94+
'org/osgi/framework/AdminPermission',
95+
'org/osgi/framework/Bundle',
96+
'org/osgi/framework/BundleActivator',
97+
'org/osgi/framework/BundleContext',
98+
'org/osgi/framework/BundleEvent',
99+
'org/osgi/framework/SynchronousBundleListener',
100+
'org/osgi/framework/wiring/BundleWire',
101+
'org/osgi/framework/wiring/BundleWiring'
79102
]
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.core.internal.io;
21+
22+
import java.io.IOException;
23+
import java.io.InputStream;
24+
import java.io.OutputStream;
25+
import java.util.Objects;
26+
27+
/**
28+
* Simple utility methods for file and stream copying.
29+
* All copy methods use a block size of 4096 bytes,
30+
* and close all affected streams when done.
31+
* <p>
32+
* Mainly for use within the framework,
33+
* but also useful for application code.
34+
*/
35+
public class Streams {
36+
37+
/**
38+
* Copy the contents of the given InputStream to the given OutputStream.
39+
* Closes both streams when done.
40+
*
41+
* @param in the stream to copy from
42+
* @param out the stream to copy to
43+
* @return the number of bytes copied
44+
* @throws IOException in case of I/O errors
45+
*/
46+
public static long copy(InputStream in, OutputStream out) throws IOException {
47+
Objects.requireNonNull(in, "No InputStream specified");
48+
Objects.requireNonNull(out, "No OutputStream specified");
49+
final byte[] buffer = new byte[8192];
50+
boolean success = false;
51+
try {
52+
long byteCount = 0;
53+
int bytesRead;
54+
while ((bytesRead = in.read(buffer)) != -1) {
55+
out.write(buffer, 0, bytesRead);
56+
byteCount += bytesRead;
57+
}
58+
out.flush();
59+
success = true;
60+
return byteCount;
61+
} finally {
62+
if (success) {
63+
IOUtils.close(in, out);
64+
} else {
65+
IOUtils.closeWhileHandlingException(in, out);
66+
}
67+
}
68+
}
69+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.core.internal.io;
21+
22+
import java.io.IOException;
23+
import java.io.InputStream;
24+
import java.io.OutputStream;
25+
26+
/**
27+
* Simple utility methods for file and stream copying.
28+
* All copy methods use a block size of 4096 bytes,
29+
* and close all affected streams when done.
30+
* <p>
31+
* Mainly for use within the framework,
32+
* but also useful for application code.
33+
*/
34+
public abstract class Streams {
35+
36+
/**
37+
* Copy the contents of the given InputStream to the given OutputStream.
38+
* Closes both streams when done.
39+
*
40+
* @param in the stream to copy from
41+
* @param out the stream to copy to
42+
* @return the number of bytes copied
43+
* @throws IOException in case of I/O errors
44+
*/
45+
public static long copy(InputStream in, OutputStream out) throws IOException {
46+
return in.transferTo(out);
47+
}
48+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.core.internal.io;
21+
22+
import org.elasticsearch.test.ESTestCase;
23+
24+
import java.io.ByteArrayInputStream;
25+
import java.io.ByteArrayOutputStream;
26+
import java.io.IOException;
27+
import java.nio.charset.StandardCharsets;
28+
import java.util.Arrays;
29+
30+
import static org.hamcrest.Matchers.equalTo;
31+
32+
public class StreamsTests extends ESTestCase {
33+
public void testCopyFromInputStream() throws IOException {
34+
byte[] content = "content".getBytes(StandardCharsets.UTF_8);
35+
ByteArrayInputStream in = new ByteArrayInputStream(content);
36+
ByteArrayOutputStream out = new ByteArrayOutputStream(content.length);
37+
long count = Streams.copy(in, out);
38+
39+
assertThat(count, equalTo((long) content.length));
40+
assertThat(Arrays.equals(content, out.toByteArray()), equalTo(true));
41+
}
42+
}

plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureStorageServiceMock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
import org.elasticsearch.common.blobstore.support.PlainBlobMetaData;
2626
import org.elasticsearch.common.collect.MapBuilder;
2727
import org.elasticsearch.common.component.AbstractComponent;
28-
import org.elasticsearch.common.io.Streams;
2928
import org.elasticsearch.common.settings.Settings;
29+
import org.elasticsearch.core.internal.io.Streams;
3030

3131
import java.io.ByteArrayInputStream;
3232
import java.io.ByteArrayOutputStream;

plugins/repository-gcs/src/test/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageFixture.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import com.sun.net.httpserver.HttpHandler;
2323
import com.sun.net.httpserver.HttpServer;
2424
import org.elasticsearch.common.SuppressForbidden;
25-
import org.elasticsearch.common.io.Streams;
25+
import org.elasticsearch.core.internal.io.Streams;
2626
import org.elasticsearch.mocksocket.MockHttpServer;
2727
import org.elasticsearch.repositories.gcs.GoogleCloudStorageTestServer.Response;
2828

server/src/main/java/org/elasticsearch/common/blobstore/fs/FsBlobContainer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import org.elasticsearch.common.blobstore.BlobPath;
2525
import org.elasticsearch.common.blobstore.support.AbstractBlobContainer;
2626
import org.elasticsearch.common.blobstore.support.PlainBlobMetaData;
27-
import org.elasticsearch.common.io.Streams;
27+
import org.elasticsearch.core.internal.io.Streams;
2828

2929
import java.io.BufferedInputStream;
3030
import java.io.FileNotFoundException;
@@ -128,7 +128,7 @@ public void writeBlob(String blobName, InputStream inputStream, long blobSize) t
128128
}
129129
final Path file = path.resolve(blobName);
130130
try (OutputStream outputStream = Files.newOutputStream(file, StandardOpenOption.CREATE_NEW)) {
131-
Streams.copy(inputStream, outputStream, new byte[blobStore.bufferSizeInBytes()]);
131+
Streams.copy(inputStream, outputStream);
132132
}
133133
IOUtils.fsync(file, false);
134134
IOUtils.fsync(path, true);

server/src/main/java/org/elasticsearch/common/compress/CompressorFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121

2222
import org.elasticsearch.common.Nullable;
2323
import org.elasticsearch.common.bytes.BytesReference;
24-
import org.elasticsearch.common.io.Streams;
2524
import org.elasticsearch.common.io.stream.BytesStreamOutput;
2625
import org.elasticsearch.common.io.stream.StreamInput;
2726
import org.elasticsearch.common.xcontent.XContentHelper;
2827
import org.elasticsearch.common.xcontent.XContentType;
28+
import org.elasticsearch.core.internal.io.Streams;
2929

3030
import java.io.IOException;
3131
import java.util.Objects;

server/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import com.fasterxml.jackson.core.util.DefaultIndenter;
2929
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
3030
import com.fasterxml.jackson.core.util.JsonGeneratorDelegate;
31-
import org.elasticsearch.common.io.Streams;
3231
import org.elasticsearch.common.xcontent.DeprecationHandler;
3332
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
3433
import org.elasticsearch.common.xcontent.XContent;
@@ -38,6 +37,7 @@
3837
import org.elasticsearch.common.xcontent.XContentParser;
3938
import org.elasticsearch.common.xcontent.XContentType;
4039
import org.elasticsearch.common.xcontent.support.filtering.FilterPathBasedFilter;
40+
import org.elasticsearch.core.internal.io.Streams;
4141

4242
import java.io.BufferedInputStream;
4343
import java.io.IOException;

server/src/main/java/org/elasticsearch/indices/recovery/RecoverySourceHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@
3838
import org.elasticsearch.common.Nullable;
3939
import org.elasticsearch.common.StopWatch;
4040
import org.elasticsearch.common.bytes.BytesArray;
41-
import org.elasticsearch.common.io.Streams;
4241
import org.elasticsearch.common.lease.Releasable;
4342
import org.elasticsearch.common.logging.Loggers;
4443
import org.elasticsearch.common.lucene.store.InputStreamIndexInput;
4544
import org.elasticsearch.common.settings.Settings;
4645
import org.elasticsearch.common.unit.ByteSizeValue;
4746
import org.elasticsearch.common.util.CancellableThreads;
47+
import org.elasticsearch.core.internal.io.Streams;
4848
import org.elasticsearch.index.engine.Engine;
4949
import org.elasticsearch.index.engine.RecoveryEngineException;
5050
import org.elasticsearch.index.seqno.LocalCheckpointTracker;

server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
import org.elasticsearch.common.collect.Tuple;
5656
import org.elasticsearch.common.component.AbstractLifecycleComponent;
5757
import org.elasticsearch.common.compress.NotXContentException;
58-
import org.elasticsearch.common.io.Streams;
5958
import org.elasticsearch.common.io.stream.BytesStreamOutput;
6059
import org.elasticsearch.common.io.stream.OutputStreamStreamOutput;
6160
import org.elasticsearch.common.io.stream.StreamOutput;
@@ -75,6 +74,7 @@
7574
import org.elasticsearch.common.xcontent.XContentHelper;
7675
import org.elasticsearch.common.xcontent.XContentParser;
7776
import org.elasticsearch.common.xcontent.XContentType;
77+
import org.elasticsearch.core.internal.io.Streams;
7878
import org.elasticsearch.index.shard.IndexShard;
7979
import org.elasticsearch.index.shard.ShardId;
8080
import org.elasticsearch.index.snapshots.IndexShardRestoreFailedException;

server/src/main/java/org/elasticsearch/repositories/blobstore/ChecksumBlobStoreFormat.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.elasticsearch.common.bytes.BytesArray;
2929
import org.elasticsearch.common.bytes.BytesReference;
3030
import org.elasticsearch.common.compress.CompressorFactory;
31-
import org.elasticsearch.common.io.Streams;
3231
import org.elasticsearch.common.io.stream.BytesStreamOutput;
3332
import org.elasticsearch.common.io.stream.StreamOutput;
3433
import org.elasticsearch.common.lucene.store.ByteArrayIndexInput;
@@ -39,6 +38,7 @@
3938
import org.elasticsearch.common.xcontent.XContentFactory;
4039
import org.elasticsearch.common.xcontent.XContentParser;
4140
import org.elasticsearch.common.xcontent.XContentType;
41+
import org.elasticsearch.core.internal.io.Streams;
4242
import org.elasticsearch.gateway.CorruptStateException;
4343

4444
import java.io.ByteArrayOutputStream;

server/src/main/java/org/elasticsearch/rest/RestController.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@
2727
import org.elasticsearch.common.breaker.CircuitBreaker;
2828
import org.elasticsearch.common.bytes.BytesArray;
2929
import org.elasticsearch.common.component.AbstractComponent;
30-
import org.elasticsearch.common.io.Streams;
3130
import org.elasticsearch.common.io.stream.BytesStreamOutput;
3231
import org.elasticsearch.common.logging.DeprecationLogger;
3332
import org.elasticsearch.common.path.PathTrie;
3433
import org.elasticsearch.common.settings.Settings;
3534
import org.elasticsearch.common.util.concurrent.ThreadContext;
3635
import org.elasticsearch.common.xcontent.XContentBuilder;
3736
import org.elasticsearch.common.xcontent.XContentType;
37+
import org.elasticsearch.core.internal.io.Streams;
3838
import org.elasticsearch.http.HttpServerTransport;
3939
import org.elasticsearch.indices.breaker.CircuitBreakerService;
4040
import org.elasticsearch.usage.UsageService;
@@ -51,7 +51,6 @@
5151
import java.util.Optional;
5252
import java.util.Set;
5353
import java.util.concurrent.atomic.AtomicBoolean;
54-
import java.util.function.Supplier;
5554
import java.util.function.UnaryOperator;
5655

5756
import static org.elasticsearch.rest.RestStatus.BAD_REQUEST;

server/src/main/java/org/elasticsearch/tasks/TaskResultsService.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@
1919
package org.elasticsearch.tasks;
2020

2121
import org.apache.logging.log4j.message.ParameterizedMessage;
22-
import org.apache.logging.log4j.util.Supplier;
23-
import org.elasticsearch.core.internal.io.IOUtils;
2422
import org.elasticsearch.ElasticsearchException;
2523
import org.elasticsearch.ExceptionsHelper;
24+
import org.elasticsearch.ResourceAlreadyExistsException;
2625
import org.elasticsearch.action.ActionListener;
2726
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
2827
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
@@ -38,13 +37,12 @@
3837
import org.elasticsearch.cluster.service.ClusterService;
3938
import org.elasticsearch.common.component.AbstractComponent;
4039
import org.elasticsearch.common.inject.Inject;
41-
import org.elasticsearch.common.io.Streams;
4240
import org.elasticsearch.common.settings.Settings;
4341
import org.elasticsearch.common.xcontent.ToXContent;
4442
import org.elasticsearch.common.xcontent.XContentBuilder;
4543
import org.elasticsearch.common.xcontent.XContentFactory;
46-
import org.elasticsearch.ResourceAlreadyExistsException;
4744
import org.elasticsearch.common.xcontent.XContentType;
45+
import org.elasticsearch.core.internal.io.Streams;
4846

4947
import java.io.ByteArrayOutputStream;
5048
import java.io.IOException;

0 commit comments

Comments
 (0)