Skip to content

Commit

Permalink
[7.x] Upgrade Azure repository SDK to v12 (#66333)
Browse files Browse the repository at this point in the history
Upgrade Azure repository to the latest non blocking Azure SDK.

Closes #43309

Backport of #65140

Co-authored-by: Ryan Ernst <[email protected]>
  • Loading branch information
fcofdez and rjernst authored Dec 15, 2020
1 parent acdc34b commit f04a74b
Show file tree
Hide file tree
Showing 79 changed files with 3,548 additions and 980 deletions.
4 changes: 3 additions & 1 deletion buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ dependencies {
api 'com.avast.gradle:gradle-docker-compose-plugin:0.13.4'
api 'org.apache.maven:maven-model:3.6.2'
api 'com.networknt:json-schema-validator:1.0.36'

api 'org.ow2.asm:asm:9.0'
api 'org.ow2.asm:asm-tree:9.0'

compileOnly "com.puppycrawl.tools:checkstyle:${props.getProperty('checkstyle')}"
testImplementation "com.puppycrawl.tools:checkstyle:${props.getProperty('checkstyle')}"
testFixturesApi "junit:junit:${props.getProperty('junit')}"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.gradle;

import org.gradle.api.DefaultTask;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InnerClassNode;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.List;
import java.util.function.Consumer;

import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;

/**
* A task to manipulate an existing class file.
*/
public class JavaClassPublicifier extends DefaultTask {

private List<String> classFiles;
private DirectoryProperty inputDir;
private DirectoryProperty outputDir;

public JavaClassPublicifier() {
this.inputDir = getProject().getObjects().directoryProperty();
this.outputDir = getProject().getObjects().directoryProperty();
}

@Input
public List<String> getClassFiles() {
return classFiles;
}

public void setClassFiles(List<String> classFiles) {
this.classFiles = classFiles;
}

@InputDirectory
public DirectoryProperty getInputDir() {
return inputDir;
}

@OutputDirectory
public DirectoryProperty getOutputDir() {
return outputDir;
}

@TaskAction
public void adapt() throws IOException {

for (String classFile : classFiles) {
adjustClass(classFile, classNode -> {
classNode.access &= ~ACC_PRIVATE;
classNode.access |= ACC_PUBLIC;

if (classFile.contains("$")) {
// java inexplicably has an inner class contain itself as an inner class...
makeInnerClassPublic(classNode, classNode.name.split("\\$")[1]);
}
});

if (classFile.contains("$")) {
// for inner classes, also need to adjust the parent
String[] parts = classFile.split("\\$");
String parentClassFile = parts[0] + ".class";
String innerClass = parts[1].split("\\.")[0];
adjustClass(parentClassFile, classNode -> makeInnerClassPublic(classNode, innerClass));
}
}
}

private static void makeInnerClassPublic(ClassNode classNode, String innerClass) {
InnerClassNode innerClassNode = classNode.innerClasses.stream().filter(node -> node.innerName.equals(innerClass)).findFirst().get();
innerClassNode.access &= ~ACC_PRIVATE;
innerClassNode.access |= ACC_PUBLIC;
}

private void writeClass(String classFile, ClassNode classNode) throws IOException {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
classNode.accept(classWriter);

File outputFile = outputDir.get().file(classFile).getAsFile();
outputFile.getParentFile().mkdirs();
Files.write(outputFile.toPath(), classWriter.toByteArray());
}

private void adjustClass(String classFile, Consumer<ClassNode> adjustor) throws IOException {
try (InputStream is = Files.newInputStream(inputDir.get().file(classFile).getAsFile().toPath())) {
ClassReader classReader = new ClassReader(is);
ClassNode classNode = new ClassNode();
classReader.accept(classNode, ClassReader.EXPAND_FRAMES);
adjustor.accept(classNode);
writeClass(classFile, classNode);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,33 @@ public class LicenseAnalyzer {
Pattern.DOTALL
)
),
new LicenseMatcher(
"MIT-0",
true,
false,
Pattern.compile(
("MIT No Attribution\n"
+ "Copyright .+\n"
+ "\n"
+ "Permission is hereby granted, free of charge, to any person obtaining a copy of "
+ "this software and associated documentation files \\(the \"Software\"\\), to deal in the Software without "
+ "restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, "
+ "and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so.\n"
+ "\n"
+ "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, "
+ "INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND "
+ "NONINFRINGEMENT\\. IN NO EVENT SHALL THE AUTHORS OR "
+ "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR "
+ "OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n")
.replaceAll("\\s+", "\\\\s*"),
Pattern.DOTALL
)
),
new LicenseMatcher("MPL-1.1", true, false, Pattern.compile("Mozilla Public License.*Version 1.1", Pattern.DOTALL)),
new LicenseMatcher("MPL-2.0", true, false, Pattern.compile("Mozilla\\s*Public\\s*License\\s*Version\\s*2\\.0", Pattern.DOTALL)),
new LicenseMatcher("XZ", false, false, Pattern.compile("Licensing of XZ for Java", Pattern.DOTALL)),
new LicenseMatcher("EPL-2.0", true, false, Pattern.compile("Eclipse Public License - v 2.0", Pattern.DOTALL)),
new LicenseMatcher("EDL-1.0", true, false, Pattern.compile("Eclipse Distribution License - v 1.0", Pattern.DOTALL)),
new LicenseMatcher("LGPL-2.1", true, true, Pattern.compile("GNU LESSER GENERAL PUBLIC LICENSE.*Version 2.1", Pattern.DOTALL)),
new LicenseMatcher("LGPL-3.0", true, true, Pattern.compile("GNU LESSER GENERAL PUBLIC LICENSE.*Version 3", Pattern.DOTALL)) };

Expand Down
48 changes: 48 additions & 0 deletions plugins/repository-azure/azure-storage-blob/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import org.elasticsearch.gradle.JavaClassPublicifier;

apply plugin: 'elasticsearch.java'
apply plugin: 'com.github.johnrengelman.shadow'

configurations {
originalJar {
transitive = false
}
}

dependencies {
originalJar "com.azure:azure-storage-blob:${project.parent.versions.azure}"
implementation "com.azure:azure-storage-blob:${project.parent.versions.azure}"
}

// We have to rewrite the service classes to make them public to avoid
// granting the permission "java.lang.reflect.ReflectPermission" "newProxyInPackage"
// to this plugin.
//
// There are plans to make those public in the azure sdk side, but in the meanwhile
// we just do this workaround
// https://github.com/Azure/azure-sdk-for-java/issues/12829#issuecomment-736755543
List<String> classesToRewrite = ['com/azure/storage/blob/implementation/AppendBlobsImpl$AppendBlobsService.class',
'com/azure/storage/blob/implementation/BlobsImpl$BlobsService.class',
'com/azure/storage/blob/implementation/BlockBlobsImpl$BlockBlobsService.class',
'com/azure/storage/blob/implementation/ContainersImpl$ContainersService.class',
'com/azure/storage/blob/implementation/DirectorysImpl$DirectorysService.class',
'com/azure/storage/blob/implementation/PageBlobsImpl$PageBlobsService.class',
'com/azure/storage/blob/implementation/ServicesImpl$ServicesService.class']

tasks.create('extractClientClasses', Copy).configure {
from({ zipTree(configurations.originalJar.singleFile) }) {
include "com/azure/storage/blob/implementation/**"
}
into project.file('build/original')
}

def modifiedOutput = project.layout.buildDirectory.dir('modified')
def makePublic = tasks.create('makeClientClassesPublic', JavaClassPublicifier)
makePublic.configure {
dependsOn 'extractClientClasses'
classFiles = classesToRewrite
inputDir = project.layout.buildDirectory.dir('original')
outputDir = modifiedOutput
}

sourceSets.main.output.dir(modifiedOutput, builtBy: makePublic)
Loading

0 comments on commit f04a74b

Please sign in to comment.