feat:remove jprotoc (#13145)

* feat:remove jprotoc

* fix:add dependency and license

* fix:remove useless import

* fix:checkstyle bug

* fix:SonarCloud bug

* refactor:remove a package path

* fix:handle InterruptedException

* refactor:modify license and format code

* fix:checkstyle excluded

* Add NOTICE

* fix:remove unless notice

* refactor:code format

---------

Co-authored-by: Albumen Kevin <jhq0812@gmail.com>
Co-authored-by: pengxiaoyu <pengxiaoyu@shengquganmes.com>
This commit is contained in:
XiaoYu 2023-10-19 12:32:38 +08:00 committed by GitHub
parent c98c4873ff
commit d0c41f512e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1445 additions and 64 deletions

View File

@ -104,6 +104,8 @@ header:
- 'dubbo-annotation-processor/src/main/java/org/apache/dubbo/annotation/permit/**'
- 'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/FormattingTuple.java'
- 'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/MessageFormatter.java'
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocCompilerMojo.java'
- 'dubbo-compiler/src/main/java/org/apache/dubbo/gen/utils/ProtoTypeMap.java'
comment: on-failure

20
NOTICE
View File

@ -16,3 +16,23 @@ Copyright 2014 The Netty Project
This product contains code form the t-digest Project:
The code for the t-digest was originally authored by Ted Dunning
Adrien Grand contributed the heart of the AVLTreeDigest (https://github.com/jpountz)
This product contains the following code copied from Maven Protocol Buffers Plugin:
dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocCompilerMojo.java
Maven Protocol Buffers Plugin
=============================
Copyright (c) 2016 Maven Protocol Buffers Plugin Authors. All rights reserved.
This product contains the following code copied from grpc-java-contrib:
dubbo-compiler/src/main/java/org/apache/dubbo/gen/utils/ProtoTypeMap.java
Some portions of this file Copyright (c) 2019, Salesforce.com, Inc. and licensed under the BSD 3-Clause License
grpc-java-contrib
====================
Copyright (c) 2019, Salesforce.com, Inc.
All rights reserved.

137
dubbo-compiler/README.md Normal file
View File

@ -0,0 +1,137 @@
## dubbo-complier
> dubbo-complier supports generating code based on .proto files
### How to use
#### 1.Define Proto file
greeter.proto
```protobuf
syntax = "proto3";
option java_multiple_files = true;
option java_package = "org.apache.dubbo.demo";
option java_outer_classname = "DemoServiceProto";
option objc_class_prefix = "DEMOSRV";
package demoservice;
// The demo service definition.
service DemoService {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
```
#### 2.Use dubbo-maven-plugin,rather than ```protobuf-maven-plugin```
now dubbo support his own protoc plugin base on dubbo-maven-plugin
```xml
<plugin>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-maven-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<dubboVersion>3.3.0</dubboVersion>
<dubboGenerateType>dubbo3</dubboGenerateType>
<protocExecutable>protoc</protocExecutable>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
</configuration>
</plugin>
```
#### 3.generate file
```java
/*
* 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.dubbo.demo;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
public final class DemoServiceDubbo {
private static final AtomicBoolean registered = new AtomicBoolean();
private static Class<?> init() {
Class<?> clazz = null;
try {
clazz = Class.forName(DemoServiceDubbo.class.getName());
if (registered.compareAndSet(false, true)) {
org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller(
org.apache.dubbo.demo.HelloReply.getDefaultInstance());
org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller(
org.apache.dubbo.demo.HelloRequest.getDefaultInstance());
}
} catch (ClassNotFoundException e) {
// ignore
}
return clazz;
}
private DemoServiceDubbo() {}
public static final String SERVICE_NAME = "org.apache.dubbo.demo.DemoService";
/**
* Code generated for Dubbo
*/
public interface IDemoService extends org.apache.dubbo.rpc.model.DubboStub {
static Class<?> clazz = init();
org.apache.dubbo.demo.HelloReply sayHello(org.apache.dubbo.demo.HelloRequest request);
CompletableFuture<org.apache.dubbo.demo.HelloReply> sayHelloAsync(org.apache.dubbo.demo.HelloRequest request);
}
}
```
#### 4.others
dubbo-maven-plugin protoc mojo supported configurations
| configuration params | isRequired | explain | default | eg |
|:----------------------|------------|------------------------------------------------|------------------------------------------------------------|----------------------------------------------------------------------------|
| dubboVersion | true | dubbo version ,use for find Generator | ${dubbo.version} | 3.3.0 |
| dubboGenerateType | true | dubbo generator type | dubbo3 | grpc |
| protocExecutable | false | protoc executable,you can use local protoc.exe | | protoc |
| protocArtifact | false | download protoc from maven artifact | | com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} |
| protoSourceDir | true | .proto files dir | ${basedir}/src/main/proto | ./proto |
| outputDir | true | generated file output dir | ${project.build.directory}/generated-sources/protobuf/java | ${basedir}/src/main/java |
| protocPluginDirectory | false | protoc plugin dir | ${project.build.directory}/protoc-plugins | ./target/protoc-plugins |

View File

@ -37,8 +37,8 @@
<dependencies>
<dependency>
<groupId>com.salesforce.servicelibs</groupId>
<artifactId>jprotoc</artifactId>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
</dependency>
<dependency>
<groupId>io.grpc</groupId>

View File

@ -16,6 +16,11 @@
*/
package org.apache.dubbo.gen;
import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import com.github.mustachejava.MustacheFactory;
import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.html.HtmlEscapers;
import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
@ -23,22 +28,23 @@ import com.google.protobuf.DescriptorProtos.FileOptions;
import com.google.protobuf.DescriptorProtos.MethodDescriptorProto;
import com.google.protobuf.DescriptorProtos.ServiceDescriptorProto;
import com.google.protobuf.DescriptorProtos.SourceCodeInfo.Location;
import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.Feature;
import com.google.protobuf.compiler.PluginProtos;
import com.salesforce.jprotoc.Generator;
import com.salesforce.jprotoc.GeneratorException;
import com.salesforce.jprotoc.ProtoTypeMap;
import org.apache.dubbo.gen.utils.ProtoTypeMap;
import javax.annotation.Nonnull;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public abstract class AbstractGenerator extends Generator {
public abstract class AbstractGenerator {
private static final MustacheFactory MUSTACHE_FACTORY = new DefaultMustacheFactory();
private static final int SERVICE_NUMBER_OF_PATHS = 2;
private static final int METHOD_NUMBER_OF_PATHS = 4;
@ -58,10 +64,6 @@ public abstract class AbstractGenerator extends Generator {
return getClassPrefix() + getClassSuffix() + "InterfaceStub.mustache";
}
@Override
protected List<Feature> supportedFeatures() {
return Collections.singletonList(Feature.FEATURE_PROTO3_OPTIONAL);
}
private String getServiceJavaDocPrefix() {
return " ";
@ -71,9 +73,7 @@ public abstract class AbstractGenerator extends Generator {
return " ";
}
@Override
public List<PluginProtos.CodeGeneratorResponse.File> generateFiles(
PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
public List<PluginProtos.CodeGeneratorResponse.File> generateFiles(PluginProtos.CodeGeneratorRequest request) {
final ProtoTypeMap typeMap = ProtoTypeMap.of(request.getProtoFileList());
List<FileDescriptorProto> protosToGenerate = request.getProtoFileList().stream()
@ -85,12 +85,12 @@ public abstract class AbstractGenerator extends Generator {
}
private List<ServiceContext> findServices(List<FileDescriptorProto> protos,
ProtoTypeMap typeMap) {
ProtoTypeMap typeMap) {
List<ServiceContext> contexts = new ArrayList<>();
protos.forEach(fileProto -> {
for (int serviceNumber = 0; serviceNumber < fileProto.getServiceCount();
serviceNumber++) {
serviceNumber++) {
ServiceContext serviceContext = buildServiceContext(
fileProto.getService(serviceNumber),
typeMap,
@ -127,7 +127,7 @@ public abstract class AbstractGenerator extends Generator {
}
private ServiceContext buildServiceContext(ServiceDescriptorProto serviceProto,
ProtoTypeMap typeMap, List<Location> locations, int serviceNumber) {
ProtoTypeMap typeMap, List<Location> locations, int serviceNumber) {
ServiceContext serviceContext = new ServiceContext();
serviceContext.fileName =
getClassPrefix() + serviceProto.getName() + getClassSuffix() + ".java";
@ -170,7 +170,7 @@ public abstract class AbstractGenerator extends Generator {
}
private MethodContext buildMethodContext(MethodDescriptorProto methodProto,
ProtoTypeMap typeMap, List<Location> locations, int methodNumber) {
ProtoTypeMap typeMap, List<Location> locations, int methodNumber) {
MethodContext methodContext = new MethodContext();
methodContext.originMethodName = methodProto.getName();
methodContext.methodName = lowerCaseFirst(methodProto.getName());
@ -261,6 +261,20 @@ public abstract class AbstractGenerator extends Generator {
return files;
}
protected String applyTemplate(@Nonnull String resourcePath, @Nonnull Object generatorContext) {
Preconditions.checkNotNull(resourcePath, "resourcePath");
Preconditions.checkNotNull(generatorContext, "generatorContext");
InputStream resource = MustacheFactory.class.getClassLoader().getResourceAsStream(resourcePath);
if (resource == null) {
throw new RuntimeException("Could not find resource " + resourcePath);
} else {
InputStreamReader resourceReader = new InputStreamReader(resource, Charsets.UTF_8);
Mustache template = MUSTACHE_FACTORY.compile(resourceReader, resourcePath);
return template.execute(new StringWriter(), generatorContext).toString();
}
}
private String absoluteDir(ServiceContext ctx) {
return ctx.packageName.replace('.', '/');
}

View File

@ -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.dubbo.gen;
import com.google.protobuf.compiler.PluginProtos;
import java.io.IOException;
import java.util.List;
public class DubboGeneratorPlugin {
public static void generate(AbstractGenerator generator) {
try{
PluginProtos.CodeGeneratorRequest request = PluginProtos.CodeGeneratorRequest.parseFrom(System.in);
List<PluginProtos.CodeGeneratorResponse.File> files = generator.generateFiles(request);
PluginProtos.CodeGeneratorResponse.newBuilder().addAllFile(files).setSupportedFeatures(PluginProtos.CodeGeneratorResponse.Feature.FEATURE_PROTO3_OPTIONAL.getNumber()).build().writeTo(System.out);
}catch (Exception e){
try {
PluginProtos.CodeGeneratorResponse.newBuilder().setError(e.getMessage()).build().writeTo(System.out);
} catch (IOException var6) {
exit(e);
}
}catch (Throwable var8) {
exit(var8);
}
}
public static void exit(Throwable e){
e.printStackTrace(System.err);
System.exit(1);
}
}

View File

@ -17,17 +17,12 @@
package org.apache.dubbo.gen.dubbo;
import org.apache.dubbo.gen.AbstractGenerator;
import com.salesforce.jprotoc.ProtocPlugin;
import org.apache.dubbo.gen.DubboGeneratorPlugin;
public class Dubbo3Generator extends AbstractGenerator {
public static void main(String[] args) {
if (args.length == 0) {
ProtocPlugin.generate(new Dubbo3Generator());
} else {
ProtocPlugin.debug(new Dubbo3Generator(), args[0]);
}
DubboGeneratorPlugin.generate(new Dubbo3Generator());
}
@Override

View File

@ -17,17 +17,13 @@
package org.apache.dubbo.gen.dubbo;
import org.apache.dubbo.gen.AbstractGenerator;
import org.apache.dubbo.gen.DubboGeneratorPlugin;
import com.salesforce.jprotoc.ProtocPlugin;
public class DubboGenerator extends AbstractGenerator {
public static void main(String[] args) {
if (args.length == 0) {
ProtocPlugin.generate(new DubboGenerator());
} else {
ProtocPlugin.debug(new DubboGenerator(), args[0]);
}
DubboGeneratorPlugin.generate(new DubboGenerator());
}
@Override

View File

@ -17,17 +17,13 @@
package org.apache.dubbo.gen.grpc;
import org.apache.dubbo.gen.AbstractGenerator;
import org.apache.dubbo.gen.DubboGeneratorPlugin;
import com.salesforce.jprotoc.ProtocPlugin;
public class DubboGrpcGenerator extends AbstractGenerator {
public static void main(String[] args) {
if (args.length == 0) {
ProtocPlugin.generate(new DubboGrpcGenerator());
} else {
ProtocPlugin.debug(new DubboGrpcGenerator(), args[0]);
}
DubboGeneratorPlugin.generate(new DubboGrpcGenerator());
}
@Override

View File

@ -17,8 +17,9 @@
package org.apache.dubbo.gen.grpc.reactive;
import org.apache.dubbo.gen.AbstractGenerator;
import org.apache.dubbo.gen.DubboGeneratorPlugin;
import com.salesforce.jprotoc.ProtocPlugin;
public class ReactorDubboGrpcGenerator extends AbstractGenerator {
@ -33,10 +34,6 @@ public class ReactorDubboGrpcGenerator extends AbstractGenerator {
}
public static void main(String[] args) {
if (args.length == 0) {
ProtocPlugin.generate(new ReactorDubboGrpcGenerator());
} else {
ProtocPlugin.debug(new ReactorDubboGrpcGenerator(), args[0]);
}
DubboGeneratorPlugin.generate(new ReactorDubboGrpcGenerator());
}
}

View File

@ -17,8 +17,7 @@
package org.apache.dubbo.gen.grpc.reactive;
import org.apache.dubbo.gen.AbstractGenerator;
import com.salesforce.jprotoc.ProtocPlugin;
import org.apache.dubbo.gen.DubboGeneratorPlugin;
public class RxDubboGrpcGenerator extends AbstractGenerator {
@Override
@ -32,10 +31,6 @@ public class RxDubboGrpcGenerator extends AbstractGenerator {
}
public static void main(String[] args) {
if (args.length == 0) {
ProtocPlugin.generate(new RxDubboGrpcGenerator());
} else {
ProtocPlugin.debug(new RxDubboGrpcGenerator(), args[0]);
}
DubboGeneratorPlugin.generate(new RxDubboGrpcGenerator());
}
}

View File

@ -17,17 +17,12 @@
package org.apache.dubbo.gen.tri;
import org.apache.dubbo.gen.AbstractGenerator;
import com.salesforce.jprotoc.ProtocPlugin;
import org.apache.dubbo.gen.DubboGeneratorPlugin;
public class Dubbo3TripleGenerator extends AbstractGenerator {
public static void main(String[] args) {
if (args.length == 0) {
ProtocPlugin.generate(new Dubbo3TripleGenerator());
} else {
ProtocPlugin.debug(new Dubbo3TripleGenerator(), args[0]);
}
DubboGeneratorPlugin.generate(new Dubbo3TripleGenerator());
}
@Override

View File

@ -17,17 +17,13 @@
package org.apache.dubbo.gen.tri.reactive;
import com.salesforce.jprotoc.ProtocPlugin;
import org.apache.dubbo.gen.AbstractGenerator;
import org.apache.dubbo.gen.DubboGeneratorPlugin;
public class ReactorDubbo3TripleGenerator extends AbstractGenerator {
public static void main(String[] args) {
if (args.length == 0) {
ProtocPlugin.generate(new ReactorDubbo3TripleGenerator());
} else {
ProtocPlugin.debug(new ReactorDubbo3TripleGenerator(), args[0]);
}
DubboGeneratorPlugin.generate(new ReactorDubbo3TripleGenerator());
}
@Override

View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2019, Salesforce.com, Inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
package org.apache.dubbo.gen.utils;
import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.protobuf.DescriptorProtos;
import javax.annotation.Nonnull;
import java.util.Collection;
public final class ProtoTypeMap {
private static final Joiner DOT_JOINER = Joiner.on('.').skipNulls();
private final ImmutableMap<String, String> types;
private ProtoTypeMap(@Nonnull ImmutableMap<String, String> types) {
Preconditions.checkNotNull(types, "types");
this.types = types;
}
public static ProtoTypeMap of(@Nonnull Collection<DescriptorProtos.FileDescriptorProto> fileDescriptorProtos) {
Preconditions.checkNotNull(fileDescriptorProtos, "fileDescriptorProtos");
Preconditions.checkArgument(!fileDescriptorProtos.isEmpty(), "fileDescriptorProtos.isEmpty()");
ImmutableMap.Builder<String, String> types = ImmutableMap.builder();
for (DescriptorProtos.FileDescriptorProto fileDescriptor : fileDescriptorProtos) {
DescriptorProtos.FileOptions fileOptions = fileDescriptor.getOptions();
String protoPackage = fileDescriptor.hasPackage() ? "." + fileDescriptor.getPackage() : "";
String javaPackage = Strings.emptyToNull(fileOptions.hasJavaPackage() ? fileOptions.getJavaPackage() : fileDescriptor.getPackage());
String enclosingClassName = fileOptions.getJavaMultipleFiles() ? null : getJavaOuterClassname(fileDescriptor, fileOptions);
fileDescriptor.getEnumTypeList().forEach((e) -> {
types.put(protoPackage + "." + e.getName(), DOT_JOINER.join(javaPackage, enclosingClassName, new Object[]{e.getName()}));
});
fileDescriptor.getMessageTypeList().forEach((m) -> {
recursivelyAddTypes(types, m, protoPackage, enclosingClassName, javaPackage);
});
}
return new ProtoTypeMap(types.build());
}
private static void recursivelyAddTypes(ImmutableMap.Builder<String, String> types, DescriptorProtos.DescriptorProto m, String protoPackage, String enclosingClassName, String javaPackage) {
String protoTypeName = protoPackage + "." + m.getName();
types.put(protoTypeName, DOT_JOINER.join(javaPackage, enclosingClassName, new Object[]{m.getName()}));
m.getEnumTypeList().forEach((e) -> {
types.put(protoPackage + "." + m.getName() + "." + e.getName(), DOT_JOINER.join(javaPackage, enclosingClassName, new Object[]{m.getName(), e.getName()}));
});
m.getNestedTypeList().forEach((n) -> {
recursivelyAddTypes(types, n, protoPackage + "." + m.getName(), DOT_JOINER.join(enclosingClassName, m.getName(), new Object[0]), javaPackage);
});
}
public String toJavaTypeName(@Nonnull String protoTypeName) {
Preconditions.checkNotNull(protoTypeName, "protoTypeName");
return (String)this.types.get(protoTypeName);
}
private static String getJavaOuterClassname(DescriptorProtos.FileDescriptorProto fileDescriptor, DescriptorProtos.FileOptions fileOptions) {
if (fileOptions.hasJavaOuterClassname()) {
return fileOptions.getJavaOuterClassname();
} else {
String filename = fileDescriptor.getName().substring(0, fileDescriptor.getName().length() - ".proto".length());
if (filename.contains("/")) {
filename = filename.substring(filename.lastIndexOf(47) + 1);
}
filename = makeInvalidCharactersUnderscores(filename);
filename = convertToCamelCase(filename);
filename = appendOuterClassSuffix(filename, fileDescriptor);
return filename;
}
}
private static String appendOuterClassSuffix(String enclosingClassName, DescriptorProtos.FileDescriptorProto fd) {
return !fd.getEnumTypeList().stream().anyMatch((enumProto) -> {
return enumProto.getName().equals(enclosingClassName);
}) && !fd.getMessageTypeList().stream().anyMatch((messageProto) -> {
return messageProto.getName().equals(enclosingClassName);
}) && !fd.getServiceList().stream().anyMatch((serviceProto) -> {
return serviceProto.getName().equals(enclosingClassName);
}) ? enclosingClassName : enclosingClassName + "OuterClass";
}
private static String makeInvalidCharactersUnderscores(String filename) {
char[] filechars = filename.toCharArray();
for(int i = 0; i < filechars.length; ++i) {
char c = filechars[i];
if (!CharMatcher.inRange('0', '9').or(CharMatcher.inRange('A', 'Z')).or(CharMatcher.inRange('a', 'z')).matches(c)) {
filechars[i] = '_';
}
}
return new String(filechars);
}
private static String convertToCamelCase(String name) {
StringBuilder sb = new StringBuilder();
sb.append(Character.toUpperCase(name.charAt(0)));
for(int i = 1; i < name.length(); ++i) {
char c = name.charAt(i);
char prev = name.charAt(i - 1);
if (c != '_') {
if (prev != '_' && !CharMatcher.inRange('0', '9').matches(prev)) {
sb.append(c);
} else {
sb.append(Character.toUpperCase(c));
}
}
}
return sb.toString();
}
}

View File

@ -155,6 +155,7 @@
<grpc.version>1.58.0</grpc.version>
<grpc_contrib_verdion>0.8.1</grpc_contrib_verdion>
<jprotoc_version>1.2.2</jprotoc_version>
<mustache_version>0.9.10</mustache_version>
<!-- Log libs -->
<slf4j_version>1.7.36</slf4j_version>
<jcl_version>1.2</jcl_version>
@ -889,6 +890,11 @@
<artifactId>jprotoc</artifactId>
<version>${jprotoc_version}</version>
</dependency>
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>${mustache_version}</version>
</dependency>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>

View File

@ -70,6 +70,18 @@
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.sonatype.plexus</groupId>
<artifactId>plexus-build-api</artifactId>
<version>0.0.7</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,385 @@
/*
* Copyright (c) 2019 Maven Protocol Buffers Plugin Authors. All rights reserved.
*
* Licensed 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.dubbo.maven.plugin.protoc;
import org.apache.dubbo.maven.plugin.protoc.command.DefaultProtocCommandBuilder;
import org.apache.dubbo.maven.plugin.protoc.enums.DubboGenerateTypeEnum;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.maven.repository.RepositorySystem;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.Os;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.codehaus.plexus.util.cli.Commandline;
import org.sonatype.plexus.build.incremental.BuildContext;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.Arrays;
import static java.lang.String.format;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singleton;
import static org.codehaus.plexus.util.FileUtils.getFiles;
@Mojo(name = "dubbo-protoc-compiler")
public class DubboProtocCompilerMojo extends AbstractMojo {
@Parameter(property = "protoSourceDir", defaultValue = "${basedir}/src/main/proto")
private File protoSourceDir;
@Parameter(property = "outputDir", defaultValue = "${project.build.directory}/generated-sources/protobuf/java")
private File outputDir;
@Parameter(required = true, property = "dubboVersion", defaultValue = "${dubbo.version}")
private String dubboVersion;
@Parameter(required = true, readonly = true, defaultValue = "${project.remoteArtifactRepositories}")
private List<ArtifactRepository> remoteRepositories;
@Parameter(required = false, property = "protocExecutable")
private String protocExecutable;
@Parameter(required = false, property = "protocArtifact")
private String protocArtifact;
@Parameter(required = false, defaultValue = "${project.build.directory}/protoc-plugins")
private File protocPluginDirectory;
@Parameter(required = true, property = "dubboGenerateType", defaultValue = "dubbo3")
private String dubboGenerateType;
@Parameter(defaultValue = "${project}", readonly = true)
protected MavenProject project;
@Parameter(defaultValue = "${session}", readonly = true)
protected MavenSession session;
@Parameter(required = true, readonly = true, property = "localRepository")
private ArtifactRepository localRepository;
@Component
private ArtifactFactory artifactFactory;
@Component
private RepositorySystem repositorySystem;
@Component
private ResolutionErrorHandler resolutionErrorHandler;
@Component
protected MavenProjectHelper projectHelper;
@Component
protected BuildContext buildContext;
final CommandLineUtils.StringStreamConsumer output = new CommandLineUtils.StringStreamConsumer();
final CommandLineUtils.StringStreamConsumer error = new CommandLineUtils.StringStreamConsumer();
private final DefaultProtocCommandBuilder defaultProtocCommandBuilder = new DefaultProtocCommandBuilder();
private final DubboProtocPluginWrapperFactory dubboProtocPluginWrapperFactory = new DubboProtocPluginWrapperFactory();
public void execute() throws MojoExecutionException, MojoFailureException {
if (protocExecutable == null && protocArtifact != null) {
final Artifact artifact = createProtocArtifact(protocArtifact);
final File file = resolveBinaryArtifact(artifact);
protocExecutable = file.getAbsolutePath();
}
if (protocExecutable == null) {
getLog().warn("No 'protocExecutable' parameter is configured, using the default: 'protoc'");
protocExecutable = "protoc";
}
getLog().info("using protocExecutable: " + protocExecutable);
DubboProtocPlugin dubboProtocPlugin = buildDubboProtocPlugin(dubboVersion, dubboGenerateType, protocPluginDirectory);
getLog().info("build dubbo protoc plugin:" + dubboProtocPlugin + " success");
List<String> commandArgs = defaultProtocCommandBuilder.buildProtocCommandArgs(new ProtocMetaData(
protocExecutable, protoSourceDir, findAllProtoFiles(protoSourceDir), outputDir, dubboProtocPlugin
));
if (!outputDir.exists()) {
FileUtils.mkdir(outputDir.getAbsolutePath());
}
try {
int exitStatus = executeCommandLine(commandArgs);
getLog().info("execute commandLine finished with exit code: " + exitStatus);
if (exitStatus != 0) {
getLog().error("PROTOC FAILED: " + getError());
throw new MojoFailureException(
"protoc did not exit cleanly. Review output for more information.");
} else if (StringUtils.isNotBlank(getError())) {
getLog().warn("PROTOC: " + getError());
} else {
linkProtoFilesToMaven();
}
} catch (CommandLineException e) {
throw new MojoExecutionException(e);
}
}
public void linkProtoFilesToMaven() {
linkProtoSources();
linkGeneratedFiles();
}
public void linkProtoSources() {
projectHelper.addResource(project, protoSourceDir.getAbsolutePath(),
Collections.singletonList("**/*.proto*"), Collections.singletonList(""));
}
public void linkGeneratedFiles() {
project.addCompileSourceRoot(outputDir.getAbsolutePath());
buildContext.refresh(outputDir);
}
public List<File> findAllProtoFiles(final File protoSourceDir) {
if (protoSourceDir == null) {
throw new RuntimeException("'protoSourceDir' is null");
}
if (!protoSourceDir.isDirectory()) {
throw new RuntimeException(format("%s is not a directory", protoSourceDir));
}
final List<File> protoFilesInDirectory;
try {
protoFilesInDirectory = getFiles(protoSourceDir, "**/*.proto*", "");
} catch (IOException e) {
throw new RuntimeException("Unable to retrieve the list of files: " + e.getMessage(), e);
}
getLog().info("protoFilesInDirectory: " + protoFilesInDirectory);
return protoFilesInDirectory;
}
public int executeCommandLine(List<String> commandArgs) throws CommandLineException {
final Commandline cl = new Commandline();
cl.setExecutable(protocExecutable);
cl.addArguments(commandArgs.toArray(new String[]{}));
int attemptsLeft = 3;
while (true) {
try {
getLog().info("commandLine:" + cl.toString());
return CommandLineUtils.executeCommandLine(cl, null, output, error);
} catch (CommandLineException e) {
if (--attemptsLeft == 0 || e.getCause() == null) {
throw e;
}
getLog().warn("[PROTOC] Unable to invoke protoc, will retry " + attemptsLeft + " time(s)", e);
try {
Thread.sleep(1000L);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new RuntimeException(ex);
}
}
}
}
private DubboProtocPlugin buildDubboProtocPlugin(String dubboVersion, String dubboGenerateType, File protocPluginDirectory) {
DubboProtocPlugin dubboProtocPlugin = new DubboProtocPlugin();
DubboGenerateTypeEnum dubboGenerateTypeEnum = DubboGenerateTypeEnum.getByType(dubboGenerateType);
if (dubboGenerateTypeEnum == null) {
throw new RuntimeException(" can not find the dubboGenerateType: " + dubboGenerateType + ",please check it !");
}
dubboProtocPlugin.setId(dubboGenerateType);
dubboProtocPlugin.setMainClass(dubboGenerateTypeEnum.getMainClass());
dubboProtocPlugin.setDubboVersion(dubboVersion);
dubboProtocPlugin.setPluginDirectory(protocPluginDirectory);
dubboProtocPlugin.setJavaHome(System.getProperty("java.home"));
DubboProtocPluginWrapper protocPluginWrapper = dubboProtocPluginWrapperFactory.findByOs();
dubboProtocPlugin.setResolvedJars(resolvePluginDependencies());
File protocPlugin = protocPluginWrapper.createProtocPlugin(dubboProtocPlugin, getLog());
boolean debugEnabled = getLog().isDebugEnabled();
if (debugEnabled) {
getLog().debug("protocPlugin: " + protocPlugin.getAbsolutePath());
}
dubboProtocPlugin.setProtocPlugin(protocPlugin);
return dubboProtocPlugin;
}
private List<File> resolvePluginDependencies() {
List<File> resolvedJars = new ArrayList<>();
final VersionRange versionSpec;
try {
versionSpec = VersionRange.createFromVersionSpec(dubboVersion);
} catch (InvalidVersionSpecificationException e) {
throw new RuntimeException("Invalid plugin version specification", e);
}
final Artifact protocPluginArtifact =
artifactFactory.createDependencyArtifact(
"org.apache.dubbo",
"dubbo-compiler",
versionSpec,
"jar",
"",
Artifact.SCOPE_RUNTIME);
final ArtifactResolutionRequest request = new ArtifactResolutionRequest()
.setArtifact(project.getArtifact())
.setResolveRoot(false)
.setArtifactDependencies(Collections.singleton(protocPluginArtifact))
.setManagedVersionMap(emptyMap())
.setLocalRepository(localRepository)
.setRemoteRepositories(remoteRepositories)
.setOffline(session.isOffline())
.setForceUpdate(session.getRequest().isUpdateSnapshots())
.setServers(session.getRequest().getServers())
.setMirrors(session.getRequest().getMirrors())
.setProxies(session.getRequest().getProxies());
final ArtifactResolutionResult result = repositorySystem.resolve(request);
try {
resolutionErrorHandler.throwErrors(request, result);
} catch (ArtifactResolutionException e) {
throw new RuntimeException("Unable to resolve plugin artifact: " + e.getMessage(), e);
}
final Set<Artifact> artifacts = result.getArtifacts();
if (artifacts == null || artifacts.isEmpty()) {
throw new RuntimeException("Unable to resolve plugin artifact");
}
for (final Artifact artifact : artifacts) {
resolvedJars.add(artifact.getFile());
}
if (getLog().isDebugEnabled()) {
getLog().debug("Resolved jars: " + resolvedJars);
}
return resolvedJars;
}
protected Artifact createProtocArtifact(final String artifactSpec) {
final String[] parts = artifactSpec.split(":");
if (parts.length < 3 || parts.length > 5) {
throw new RuntimeException(
"Invalid artifact specification format"
+ ", expected: groupId:artifactId:version[:type[:classifier]]"
+ ", actual: " + artifactSpec);
}
final String type = parts.length >= 4 ? parts[3] : "exe";
final String classifier = parts.length == 5 ? parts[4] : null;
//parts: [com.google.protobuf, protoc, 3.6.0, exe, osx-x86_64]
getLog().info("parts: " + Arrays.toString(parts));
return createDependencyArtifact(parts[0], parts[1], parts[2], type, classifier);
}
protected Artifact createDependencyArtifact(
final String groupId,
final String artifactId,
final String version,
final String type,
final String classifier
) {
final VersionRange versionSpec;
try {
versionSpec = VersionRange.createFromVersionSpec(version);
} catch (final InvalidVersionSpecificationException e) {
throw new RuntimeException("Invalid version specification", e);
}
return artifactFactory.createDependencyArtifact(
groupId,
artifactId,
versionSpec,
type,
classifier,
Artifact.SCOPE_RUNTIME);
}
protected File resolveBinaryArtifact(final Artifact artifact) {
final ArtifactResolutionResult result;
final ArtifactResolutionRequest request = new ArtifactResolutionRequest()
.setArtifact(project.getArtifact())
.setResolveRoot(false)
.setResolveTransitively(false)
.setArtifactDependencies(singleton(artifact))
.setManagedVersionMap(emptyMap())
.setLocalRepository(localRepository)
.setRemoteRepositories(remoteRepositories)
.setOffline(session.isOffline())
.setForceUpdate(session.getRequest().isUpdateSnapshots())
.setServers(session.getRequest().getServers())
.setMirrors(session.getRequest().getMirrors())
.setProxies(session.getRequest().getProxies());
result = repositorySystem.resolve(request);
try {
resolutionErrorHandler.throwErrors(request, result);
} catch (final ArtifactResolutionException e) {
throw new RuntimeException("Unable to resolve artifact: " + e.getMessage(), e);
}
final Set<Artifact> artifacts = result.getArtifacts();
if (artifacts == null || artifacts.isEmpty()) {
throw new RuntimeException("Unable to resolve artifact");
}
final Artifact resolvedBinaryArtifact = artifacts.iterator().next();
if (getLog().isDebugEnabled()) {
getLog().debug("Resolved artifact: " + resolvedBinaryArtifact);
}
final File sourceFile = resolvedBinaryArtifact.getFile();
final String sourceFileName = sourceFile.getName();
final String targetFileName;
if (Os.isFamily(Os.FAMILY_WINDOWS) && !sourceFileName.endsWith(".exe")) {
targetFileName = sourceFileName + ".exe";
} else {
targetFileName = sourceFileName;
}
final File targetFile = new File(protocPluginDirectory, targetFileName);
if (targetFile.exists()) {
getLog().debug("Executable file already exists: " + targetFile.getAbsolutePath());
return targetFile;
}
try {
FileUtils.forceMkdir(protocPluginDirectory);
} catch (final IOException e) {
throw new RuntimeException("Unable to create directory " + protocPluginDirectory, e);
}
try {
FileUtils.copyFile(sourceFile, targetFile);
} catch (final IOException e) {
throw new RuntimeException("Unable to copy the file to " + protocPluginDirectory, e);
}
if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
boolean b = targetFile.setExecutable(true);
if (!b) {
throw new RuntimeException("Unable to make executable: " + targetFile.getAbsolutePath());
}
}
if (getLog().isDebugEnabled()) {
getLog().debug("Executable file: " + targetFile.getAbsolutePath());
}
return targetFile;
}
public String getError() {
return fixUnicodeOutput(error.getOutput());
}
public String getOutput() {
return fixUnicodeOutput(output.getOutput());
}
private static String fixUnicodeOutput(final String message) {
return new String(message.getBytes(), StandardCharsets.UTF_8);
}
}

View File

@ -0,0 +1,140 @@
/*
* 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.dubbo.maven.plugin.protoc;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class DubboProtocPlugin {
private String id;
private String mainClass;
private String dubboVersion;
private String javaHome;
private File pluginDirectory;
private List<File> resolvedJars = new ArrayList<>();
private List<String> args = new ArrayList<>();
private List<String> jvmArgs = new ArrayList<>();
private File protocPlugin = null;
public DubboProtocPlugin() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMainClass() {
return mainClass;
}
public void setMainClass(String mainClass) {
this.mainClass = mainClass;
}
public String getDubboVersion() {
return dubboVersion;
}
public void setDubboVersion(String dubboVersion) {
this.dubboVersion = dubboVersion;
}
public String getJavaHome() {
return javaHome;
}
public void setJavaHome(String javaHome) {
this.javaHome = javaHome;
}
public File getPluginDirectory() {
return pluginDirectory;
}
public void setPluginDirectory(File pluginDirectory) {
this.pluginDirectory = pluginDirectory;
}
public List<File> getResolvedJars() {
return resolvedJars;
}
public void setResolvedJars(List<File> resolvedJars) {
this.resolvedJars = resolvedJars;
}
public void addResolvedJar(File jar) {
resolvedJars.add(jar);
}
public List<String> getArgs() {
return args;
}
public void setArgs(List<String> args) {
this.args = args;
}
public void addArg(String arg) {
args.add(arg);
}
public List<String> getJvmArgs() {
return jvmArgs;
}
public void setJvmArgs(List<String> jvmArgs) {
this.jvmArgs = jvmArgs;
}
public void addJvmArg(String jvmArg) {
jvmArgs.add(jvmArg);
}
public String getPluginName() {
return "protoc-gen-" + id;
}
public File getProtocPlugin() {
return protocPlugin;
}
public void setProtocPlugin(File protocPlugin) {
this.protocPlugin = protocPlugin;
}
@Override
public String toString() {
return "DubboProtocPlugin{" +
"id='" + id + '\'' +
", mainClass='" + mainClass + '\'' +
", dubboVersion='" + dubboVersion + '\'' +
", javaHome='" + javaHome + '\'' +
", pluginDirectory=" + pluginDirectory +
", resolvedJars=" + resolvedJars +
", args=" + args +
", jvmArgs=" + jvmArgs +
", protocPlugin=" + protocPlugin +
'}';
}
}

View File

@ -0,0 +1,26 @@
/*
* 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.dubbo.maven.plugin.protoc;
import org.apache.maven.plugin.logging.Log;
import java.io.File;
public interface DubboProtocPluginWrapper {
File createProtocPlugin(DubboProtocPlugin dubboProtocPlugin, Log log);
}

View File

@ -0,0 +1,46 @@
/*
* 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.dubbo.maven.plugin.protoc;
import org.codehaus.plexus.util.Os;
import java.util.HashMap;
import java.util.Map;
public class DubboProtocPluginWrapperFactory {
private final LinuxDubboProtocPluginWrapper linuxProtocCommandBuilder = new LinuxDubboProtocPluginWrapper();
private final WinDubboProtocPluginWrapper winDubboProtocPluginWrapper = new WinDubboProtocPluginWrapper();
private final Map<String, DubboProtocPluginWrapper> dubboProtocPluginWrappers = new HashMap<>();
public DubboProtocPluginWrapperFactory() {
dubboProtocPluginWrappers.put("linux", linuxProtocCommandBuilder);
dubboProtocPluginWrappers.put("windows", winDubboProtocPluginWrapper);
}
public DubboProtocPluginWrapper findByOs() {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
return dubboProtocPluginWrappers.get("windows");
}
return dubboProtocPluginWrappers.get("linux");
}
}

View File

@ -0,0 +1,84 @@
/*
* 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.dubbo.maven.plugin.protoc;
import org.apache.maven.plugin.logging.Log;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
public class LinuxDubboProtocPluginWrapper implements DubboProtocPluginWrapper {
@Override
public File createProtocPlugin(DubboProtocPlugin dubboProtocPlugin, Log log) {
List<File> resolvedJars = dubboProtocPlugin.getResolvedJars();
createPluginDirectory(dubboProtocPlugin.getPluginDirectory());
File pluginExecutableFile = new File(dubboProtocPlugin.getPluginDirectory(), dubboProtocPlugin.getPluginName());
final File javaLocation = new File(dubboProtocPlugin.getJavaHome(), "bin/java");
if (log.isDebugEnabled()) {
log.debug("javaLocation=" + javaLocation.getAbsolutePath());
}
try (final PrintWriter out = new PrintWriter(new FileWriter(pluginExecutableFile))) {
out.println("#!/bin/sh");
out.println();
out.print("CP=");
for (int i = 0; i < resolvedJars.size(); i++) {
if (i > 0) {
out.print(":");
}
out.print("\"" + resolvedJars.get(i).getAbsolutePath() + "\"");
}
out.println();
out.print("ARGS=\"");
for (final String arg : dubboProtocPlugin.getArgs()) {
out.print(arg + " ");
}
out.println("\"");
out.print("JVMARGS=\"");
for (final String jvmArg : dubboProtocPlugin.getJvmArgs()) {
out.print(jvmArg + " ");
}
out.println("\"");
out.println();
out.println("\"" + javaLocation.getAbsolutePath() + "\" $JVMARGS -cp $CP "
+ dubboProtocPlugin.getMainClass() + " $ARGS");
out.println();
boolean b = pluginExecutableFile.setExecutable(true);
if (!b) {
throw new RuntimeException("Could not make plugin executable: " + pluginExecutableFile);
}
return pluginExecutableFile;
} catch (IOException e) {
throw new RuntimeException("Could not write plugin script file: " + pluginExecutableFile, e);
}
}
private void createPluginDirectory(File pluginDirectory) {
pluginDirectory.mkdirs();
if (!pluginDirectory.isDirectory()) {
throw new RuntimeException("Could not create protoc plugin directory: "
+ pluginDirectory.getAbsolutePath());
}
}
}

View File

@ -0,0 +1,85 @@
/*
* 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.dubbo.maven.plugin.protoc;
import java.io.File;
import java.util.List;
public class ProtocMetaData {
private String protocExecutable;
private File protoSourceDir;
private List<File> protoFiles;
private File outputDir;
private DubboProtocPlugin dubboProtocPlugin;
public ProtocMetaData() {
}
public ProtocMetaData(String protocExecutable, File protoSourceDir, List<File> protoFiles, File outputDir, DubboProtocPlugin dubboProtocPlugin) {
this.protocExecutable = protocExecutable;
this.protoSourceDir = protoSourceDir;
this.protoFiles = protoFiles;
this.outputDir = outputDir;
this.dubboProtocPlugin = dubboProtocPlugin;
}
public String getProtocExecutable() {
return protocExecutable;
}
public void setProtocExecutable(String protocExecutable) {
this.protocExecutable = protocExecutable;
}
public File getProtoSourceDir() {
return protoSourceDir;
}
public void setProtoSourceDir(File protoSourceDir) {
this.protoSourceDir = protoSourceDir;
}
public List<File> getProtoFiles() {
return protoFiles;
}
public void setProtoFiles(List<File> protoFiles) {
this.protoFiles = protoFiles;
}
public File getOutputDir() {
return outputDir;
}
public void setOutputDir(File outputDir) {
this.outputDir = outputDir;
}
public DubboProtocPlugin getDubboProtocPlugin() {
return dubboProtocPlugin;
}
public void setDubboProtocPlugin(DubboProtocPlugin dubboProtocPlugin) {
this.dubboProtocPlugin = dubboProtocPlugin;
}
}

View File

@ -0,0 +1,153 @@
/*
* 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.dubbo.maven.plugin.protoc;
import org.apache.maven.plugin.logging.Log;
import org.codehaus.plexus.util.FileUtils;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
public class WinDubboProtocPluginWrapper implements DubboProtocPluginWrapper {
private static final String DATA_MODEL_SYSPROP = "sun.arch.data.model";
private static final String WIN_JVM_DATA_MODEL_32 = "32";
private static final String WIN_JVM_DATA_MODEL_64 = "64";
private String winJvmDataModel;
private static File findJvmLocation(final File javaHome, final String... paths) {
for (final String path : paths) {
final File jvmLocation = new File(javaHome, path);
if (jvmLocation.isFile()) {
return jvmLocation;
}
}
return null;
}
@Override
public File createProtocPlugin(DubboProtocPlugin dubboProtocPlugin, Log log) {
createPluginDirectory(dubboProtocPlugin.getPluginDirectory());
final File javaHome = new File(dubboProtocPlugin.getJavaHome());
final File jvmLocation = findJvmLocation(javaHome,
"jre/bin/server/jvm.dll",
"bin/server/jvm.dll",
"jre/bin/client/jvm.dll",
"bin/client/jvm.dll");
final File winRun4JIniFile = new File(dubboProtocPlugin.getPluginDirectory(), dubboProtocPlugin.getId() + ".ini");
if (winJvmDataModel != null) {
if (!(winJvmDataModel.equals(WIN_JVM_DATA_MODEL_32) || winJvmDataModel.equals(WIN_JVM_DATA_MODEL_64))) {
throw new RuntimeException("winJvmDataModel must be '32' or '64'");
}
} else if (archDirectoryExists("amd64", dubboProtocPlugin.getJavaHome())) {
winJvmDataModel = WIN_JVM_DATA_MODEL_64;
if (log.isDebugEnabled()) {
log.debug("detected 64-bit JVM from directory structure");
}
} else if (archDirectoryExists("i386", dubboProtocPlugin.getJavaHome())) {
winJvmDataModel = WIN_JVM_DATA_MODEL_32;
if (log.isDebugEnabled()) {
log.debug("detected 32-bit JVM from directory structure");
}
} else if (System.getProperty(DATA_MODEL_SYSPROP) != null) {
winJvmDataModel = System.getProperty(DATA_MODEL_SYSPROP);
if (log.isDebugEnabled()) {
log.debug("detected " + winJvmDataModel + "-bit JVM from system property " + DATA_MODEL_SYSPROP);
}
} else {
winJvmDataModel = WIN_JVM_DATA_MODEL_32;
if (log.isDebugEnabled()) {
log.debug("defaulting to 32-bit JVM");
}
}
try (final PrintWriter out = new PrintWriter(new FileWriter(winRun4JIniFile))) {
if (jvmLocation != null) {
out.println("vm.location=" + jvmLocation.getAbsolutePath());
}
int index = 1;
for (final File resolvedJar : dubboProtocPlugin.getResolvedJars()) {
out.println("classpath." + index + "=" + resolvedJar.getAbsolutePath());
index++;
}
out.println("main.class=" + dubboProtocPlugin.getMainClass());
index = 1;
for (final String arg : dubboProtocPlugin.getArgs()) {
out.println("arg." + index + "=" + arg);
index++;
}
index = 1;
for (final String jvmArg : dubboProtocPlugin.getJvmArgs()) {
out.println("vmarg." + index + "=" + jvmArg);
index++;
}
out.println("vm.version.min=1.8");
out.println("log.level=none");
out.println("[ErrorMessages]");
out.println("show.popup=false");
} catch (IOException e) {
throw new RuntimeException(
"Could not write WinRun4J ini file: " + winRun4JIniFile.getAbsolutePath(), e);
}
final String executablePath = getWinrun4jExecutablePath();
final URL url = Thread.currentThread().getContextClassLoader().getResource(executablePath);
if (url == null) {
throw new RuntimeException(
"Could not locate WinRun4J executable at path: " + executablePath);
}
File pluginExecutableFile = getPluginExecutableFile(dubboProtocPlugin);
try {
FileUtils.copyURLToFile(url, pluginExecutableFile);
return pluginExecutableFile;
} catch (IOException e) {
throw new RuntimeException(
"Could not copy WinRun4J executable to: " + pluginExecutableFile.getAbsolutePath(), e);
}
}
private void createPluginDirectory(File pluginDirectory) {
pluginDirectory.mkdirs();
if (!pluginDirectory.isDirectory()) {
throw new RuntimeException("Could not create protoc plugin directory: "
+ pluginDirectory.getAbsolutePath());
}
}
private boolean archDirectoryExists(String arch, String javaHome) {
return javaHome != null
&& (new File(javaHome, "jre/lib/" + arch).isDirectory()
|| new File(javaHome, "lib/" + arch).isDirectory());
}
private String getWinrun4jExecutablePath() {
return "winrun4j/WinRun4J" + winJvmDataModel + ".exe";
}
public File getPluginExecutableFile(DubboProtocPlugin dubboProtocPlugin) {
return new File(dubboProtocPlugin.getPluginDirectory(), "protoc-gen-" + dubboProtocPlugin.getId() + ".exe");
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.dubbo.maven.plugin.protoc.command;
import org.apache.dubbo.maven.plugin.protoc.DubboProtocPlugin;
import org.apache.dubbo.maven.plugin.protoc.ProtocMetaData;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class DefaultProtocCommandBuilder implements ProtocCommandArgsBuilder {
@Override
public List<String> buildProtocCommandArgs(ProtocMetaData protocMetaData) {
final List<String> command = new ArrayList<>();
command.add("--proto_path=" + protocMetaData.getProtoSourceDir());
String outputOption = "--java_out=";
outputOption += protocMetaData.getOutputDir();
command.add(outputOption);
DubboProtocPlugin dubboProtocPlugin = protocMetaData.getDubboProtocPlugin();
command.add("--plugin=protoc-gen-" + dubboProtocPlugin.getId() + '=' + dubboProtocPlugin.getProtocPlugin());
command.add("--" + dubboProtocPlugin.getId() + "_out=" + protocMetaData.getOutputDir());
for (final File protoFile : protocMetaData.getProtoFiles()) {
command.add(protoFile.toString());
}
return command;
}
}

View File

@ -0,0 +1,26 @@
/*
* 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.dubbo.maven.plugin.protoc.command;
import org.apache.dubbo.maven.plugin.protoc.ProtocMetaData;
import java.util.List;
public interface ProtocCommandArgsBuilder {
List<String> buildProtocCommandArgs(ProtocMetaData protocMetaData) throws RuntimeException;
}

View File

@ -0,0 +1,60 @@
/*
* 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.dubbo.maven.plugin.protoc.enums;
public enum DubboGenerateTypeEnum {
Dubbo("dubbo","org.apache.dubbo.gen.dubbo.DubboGenerator"),
Dubbo3("dubbo3","org.apache.dubbo.gen.dubbo.Dubbo3Generator"),
Tri("tri","org.apache.dubbo.gen.tri.Dubbo3TripleGenerator"),
Tri_reactor("tri_reactor","org.apache.dubbo.gen.tri.reactive.ReactorDubbo3TripleGenerator"),
Grpc("grpc","org.apache.dubbo.gen.grpc.DubboGrpcGenerator"),
Grpc_reactor("grpc_reactor","org.apache.dubbo.gen.grpc.reactive.ReactorDubboGrpcGenerator"),
Grpc_rx("grpc_rx","org.apache.dubbo.gen.grpc.reactive.RxDubboGrpcGenerator"),
;
private String id;
private String mainClass;
DubboGenerateTypeEnum(String id, String mainClass) {
this.id = id;
this.mainClass = mainClass;
}
public static DubboGenerateTypeEnum getByType(String dubboGenerateType) {
DubboGenerateTypeEnum[] values = DubboGenerateTypeEnum.values();
for (DubboGenerateTypeEnum value : values) {
if (value.getId().equals(dubboGenerateType)) {
return value;
}
}
return null;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMainClass() {
return mainClass;
}
public void setMainClass(String mainClass) {
this.mainClass = mainClass;
}
}

View File

@ -367,6 +367,8 @@
**/org/apache/dubbo/metrics/aggregate/DubboAbstractTDigest.java,
**/org/apache/dubbo/common/logger/helpers/FormattingTuple.java,
**/org/apache/dubbo/common/logger/helpers/MessageFormatter.java,
**/org/apache/dubbo/maven/plugin/protoc/DubboProtocCompilerMojo.java,
**/org/apache/dubbo/gen/utils/ProtoTypeMap.java,
**/istio/v1/auth/**/*,
**/com/google/rpc/*,
**/generated/**/*,