• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.tradefed.invoker.shard;
17 
18 import com.android.tradefed.error.HarnessRuntimeException;
19 import com.android.tradefed.result.error.InfraErrorIdentifier;
20 
21 import com.proto.tradefed.feature.MultiPartResponse;
22 import com.proto.tradefed.feature.PartResponse;
23 
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Optional;
27 
28 /**
29  * Data-holding class in order to make sending via the feature server easier.
30  *
31  * <p>WARNING: THIS CLASS NEEDS TO BE BACKWARD COMPATIBLE WITH ITSELF AT LEAST 2 WEEKS BACK. IT MUST
32  * MESH WITH THE DEPLOYED VERSION WHICH CAN BE UP TO A COUPLE WEEKS OLD. This is because this class
33  * handles serialization and deserialization for a feature, but it must work with the lab-deployed
34  * version which is going to be an older version of this class.
35  */
36 public class DynamicShardingConnectionInfoMessage implements IDynamicShardingConnectionInfo {
37     private final String mServerName;
38     private final Integer mServerPort;
39     private final List<String> mAuthScopes;
40 
41     public static final String SERVER_NAME_KEY = "server_name";
42     public static final String SERVER_PORT_KEY = "server_port";
43     public static final String AUTH_SCOPES_KEY = "auth_scopes";
44 
DynamicShardingConnectionInfoMessage( String serverName, Integer serverPort, List<String> authScopes)45     DynamicShardingConnectionInfoMessage(
46             String serverName, Integer serverPort, List<String> authScopes) {
47         mServerName = serverName;
48         mServerPort = serverPort;
49         mAuthScopes = authScopes;
50     }
51 
fromConnectionInfo( IDynamicShardingConnectionInfo info)52     public static DynamicShardingConnectionInfoMessage fromConnectionInfo(
53             IDynamicShardingConnectionInfo info) {
54         return new DynamicShardingConnectionInfoMessage(
55                 info.getServerAddress(), info.getServerPort(), info.getAuthScopes());
56     }
57 
fromMultiPartResponse( MultiPartResponse response)58     public static DynamicShardingConnectionInfoMessage fromMultiPartResponse(
59             MultiPartResponse response) {
60         Optional<String> serverName = Optional.empty();
61         Optional<Integer> serverPort = Optional.empty();
62         List<String> authScopes = new ArrayList();
63 
64         for (PartResponse part : response.getResponsePartList()) {
65             if (part.getKey().equals(AUTH_SCOPES_KEY)) {
66                 authScopes.add(part.getValue());
67             }
68             if (part.getKey().equals(SERVER_NAME_KEY)) {
69                 if (serverName.isPresent()) {
70                     throw new HarnessRuntimeException(
71                             "Malformed dynamic sharding connection info: server name was specified"
72                                     + " more than once.",
73                             InfraErrorIdentifier.UNDETERMINED);
74                 }
75                 serverName = Optional.of(part.getValue());
76             }
77             if (part.getKey().equals(SERVER_PORT_KEY)) {
78                 if (serverPort.isPresent()) {
79                     throw new HarnessRuntimeException(
80                             "Malformed dynamic sharding connection info: server port was specified"
81                                     + " more than once.",
82                             InfraErrorIdentifier.UNDETERMINED);
83                 }
84                 serverPort = Optional.of(Integer.parseInt(part.getValue()));
85             }
86         }
87 
88         if (!serverName.isPresent()) {
89             throw new HarnessRuntimeException(
90                     "Malformed dynamic sharding connection info: server name was not specified.",
91                     InfraErrorIdentifier.UNDETERMINED);
92         }
93 
94         if (!serverPort.isPresent()) {
95             throw new HarnessRuntimeException(
96                     "Malformed dynamic sharding connection info: server port was not specified.",
97                     InfraErrorIdentifier.UNDETERMINED);
98         }
99 
100         return new DynamicShardingConnectionInfoMessage(
101                 serverName.get(), serverPort.get(), authScopes);
102     }
103 
toResponseBuilder()104     public MultiPartResponse.Builder toResponseBuilder() {
105         MultiPartResponse.Builder builder = MultiPartResponse.newBuilder();
106         builder.addResponsePart(
107                 PartResponse.newBuilder().setKey(SERVER_NAME_KEY).setValue(mServerName));
108         builder.addResponsePart(
109                 PartResponse.newBuilder().setKey(SERVER_PORT_KEY).setValue(mServerPort.toString()));
110         for (String scope : mAuthScopes) {
111             builder.addResponsePart(
112                     PartResponse.newBuilder().setKey(AUTH_SCOPES_KEY).setValue(scope));
113         }
114 
115         return builder;
116     }
117 
118     @Override
getServerAddress()119     public String getServerAddress() {
120         return mServerName;
121     }
122 
123     @Override
getServerPort()124     public Integer getServerPort() {
125         return mServerPort;
126     }
127 
128     @Override
getAuthScopes()129     public List<String> getAuthScopes() {
130         return mAuthScopes;
131     }
132 }
133