Skip to content

Commit 0845991

Browse files
stevie9868Yingjian Wu
and
Yingjian Wu
authored
Add back SetValues() as it is used internally (#579)
* addSetValues * fix test * fix test --------- Co-authored-by: Yingjian Wu <[email protected]>
1 parent 2bf2a0b commit 0845991

File tree

5 files changed

+223
-12
lines changed

5 files changed

+223
-12
lines changed

metacat-common-server/src/main/java/com/netflix/metacat/common/server/usermetadata/LookupService.java

+14-9
Original file line numberDiff line numberDiff line change
@@ -77,29 +77,34 @@ default Set<String> getValues(final Long lookupId) {
7777
*
7878
* @param name lookup name
7979
* @param values multiple values
80-
* @param includeValues whether to populate the values field in the Lookup Object
80+
* @param includeValues whether to include values in the final Lookup Object
8181
* @return updated lookup
8282
*/
83+
@Nullable
84+
default Lookup addValues(final String name, final Set<String> values, boolean includeValues) {
85+
return null;
86+
}
8387

8488
/**
8589
* Saves the lookup value.
8690
*
87-
* @param name lookup name
88-
* @param values multiple values
89-
* @param includeValues whether to include values in the final Lookup Object
91+
* @param name lookup name
92+
* @param values lookup value
9093
* @return updated lookup
9194
*/
9295
@Nullable
93-
default Lookup addValues(final String name, final Set<String> values, boolean includeValues) {
96+
default Lookup setValues(final String name, final Set<String> values) {
9497
return null;
9598
}
9699

97100
/**
98-
* Saves the lookup value.
99-
*
101+
* Save single lookup Value.
100102
* @param name lookup name
101103
* @param value lookup value
102-
* @param includeValues whether to return lookup value in the Lookup Object
103-
* @return updated lookup
104+
* @return returns the lookup with the given name.
104105
*/
106+
@Nullable
107+
default Lookup setValue(final String name, final String value) {
108+
return null;
109+
}
105110
}

metacat-functional-tests/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ configurations {
4242

4343

4444
dependencies {
45+
testImplementation project(path: ':metacat-metadata-mysql')
4546
warproject(project(path: ':metacat-war', configuration: 'archives'))
4647

4748
/*******************************
@@ -64,7 +65,6 @@ dependencies {
6465
testImplementation(project(":metacat-common-server"))
6566
testImplementation(project(":metacat-connector-hive"))
6667
testImplementation(project(":metacat-testdata-provider"))
67-
6868
functionalTestImplementation(project(":metacat-client"))
6969
functionalTestImplementation("org.apache.hadoop:hadoop-core")
7070
functionalTestImplementation("org.apache.hive:hive-exec:${hive_version}") {

metacat-functional-tests/metacat-test-cluster/docker-compose.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ services:
8989
- MYSQL_PASSWORD=metacat_user_password
9090
- MYSQL_DATABASE=metacat
9191
ports:
92-
- '3306'
92+
- '3306:3306'
9393
labels:
9494
- "com.netflix.metacat.oss.test"
9595
postgresql:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright 2016 Netflix, Inc.
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+
*/
17+
package com.netflix.metacat
18+
19+
import com.netflix.metacat.common.server.model.Lookup
20+
import com.netflix.metacat.common.server.properties.DefaultConfigImpl
21+
import com.netflix.metacat.common.server.properties.MetacatProperties
22+
import com.netflix.metacat.metadata.mysql.MySqlLookupService
23+
import org.springframework.jdbc.core.JdbcTemplate
24+
import org.springframework.jdbc.datasource.DriverManagerDataSource
25+
import spock.lang.Shared
26+
import spock.lang.Specification
27+
28+
class MySqlLookupServiceSpec extends Specification{
29+
private MySqlLookupService mySqlLookupService;
30+
private JdbcTemplate jdbcTemplate;
31+
32+
@Shared
33+
MySqlLookupService mySqlLookupService
34+
35+
@Shared
36+
JdbcTemplate jdbcTemplate
37+
38+
def setupSpec() {
39+
String jdbcUrl = "jdbc:mysql://localhost:3306/metacat"
40+
String username = "metacat_user"
41+
String password = "metacat_user_password"
42+
43+
DriverManagerDataSource dataSource = new DriverManagerDataSource()
44+
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver")
45+
dataSource.setUrl(jdbcUrl)
46+
dataSource.setUsername(username)
47+
dataSource.setPassword(password)
48+
49+
jdbcTemplate = new JdbcTemplate(dataSource)
50+
mySqlLookupService = new MySqlLookupService(new DefaultConfigImpl(new MetacatProperties()), jdbcTemplate)
51+
}
52+
53+
boolean areLookupsEqual(Lookup l1, Lookup l2) {
54+
l1.id == l2.id &&
55+
l1.name == l2.name &&
56+
l1.type == l2.type &&
57+
l1.values == l2.values &&
58+
l1.createdBy == l2.createdBy &&
59+
l1.lastUpdatedBy == l2.lastUpdatedBy
60+
}
61+
62+
def "test setValues with getValue/getValues iterative"() {
63+
setup:
64+
def values = valuesList as Set<String>
65+
def lookup = mySqlLookupService.setValues("mock", values)
66+
67+
expect:
68+
lookup.values.size() == expectedSize
69+
lookup.values == mySqlLookupService.getValues("mock")
70+
lookup.values == mySqlLookupService.getValues(lookup.id)
71+
lookup.values.contains(mySqlLookupService.getValue("mock"))
72+
areLookupsEqual(lookup, mySqlLookupService.get("mock", true))
73+
74+
where:
75+
valuesList | expectedSize
76+
["1", "2", "3"] | 3
77+
["1", "2", "3", "4"] | 4
78+
["1", "2", "3", "3", "4"] | 4
79+
["3", "4"] | 2
80+
["6"] | 1
81+
["1", "6"] | 2
82+
}
83+
84+
def "test setValues for different id"(){
85+
when:
86+
def mock1LookUp = mySqlLookupService.setValues("mock1", ["1", "2", "3"] as Set<String>)
87+
def mock2LookUp = mySqlLookupService.setValues("mock2", ["4", "5", "6"] as Set<String>)
88+
then:
89+
mock1LookUp.values == ["1", "2", "3"] as Set<String>
90+
mock1LookUp.values == mySqlLookupService.getValues("mock1")
91+
areLookupsEqual(mock1LookUp, mySqlLookupService.get("mock1", true))
92+
mock2LookUp.values == ["4", "5", "6"] as Set<String>
93+
mock2LookUp.values == mySqlLookupService.getValues("mock2")
94+
areLookupsEqual(mock2LookUp, mySqlLookupService.get("mock2", true))
95+
}
96+
97+
def "test addValues iterative"() {
98+
setup:
99+
def values = valuesList as Set<String>
100+
def lookup = mySqlLookupService.addValues("mockAdd", values, includeValues)
101+
102+
expect:
103+
if (includeValues) {
104+
lookup.values == mySqlLookupService.getValues(lookup.id)
105+
lookup.values.contains(mySqlLookupService.getValue("mockAdd"))
106+
lookup.values == mySqlLookupService.getValues("mockAdd")
107+
}
108+
lookup.values.size() == expectedSize
109+
areLookupsEqual(lookup, mySqlLookupService.get("mockAdd", includeValues))
110+
where:
111+
valuesList | expectedSize | includeValues
112+
["1", "2", "3"] | 3 | true
113+
["1", "2", "3", "4"] | 4 | true
114+
["1", "2", "3", "3", "4"] | 4 | true
115+
["3", "4"] | 4 | true
116+
["6"] | 5 | true
117+
["1", "6"] | 5 | true
118+
["1", "2", "3"] | 0 | false
119+
["1", "2", "3", "4"] | 0 | false
120+
["1", "2", "3", "3", "4"] | 0 | false
121+
["3", "4"] | 0 | false
122+
["6"] | 0 | false
123+
["1", "6"] | 0 | false
124+
}
125+
126+
def "test addValues for different id"() {
127+
setup:
128+
def mock1LookUp = mySqlLookupService.addValues("addValues_mock1", ["1", "2", "3"] as Set<String>, false)
129+
def mock2LookUp = mySqlLookupService.addValues("addValues_mock2", ["4", "5", "6"] as Set<String>, true)
130+
131+
expect:
132+
mock1LookUp.values.isEmpty()
133+
areLookupsEqual(mock1LookUp, mySqlLookupService.get("addValues_mock1", false))
134+
mock2LookUp.values == ["4", "5", "6"] as Set<String>
135+
mock2LookUp.values == mySqlLookupService.getValues("addValues_mock2")
136+
areLookupsEqual(mock2LookUp, mySqlLookupService.get("addValues_mock2", true))
137+
}
138+
139+
def "test setValue for different id"(){
140+
when:
141+
def mock1LookUp = mySqlLookupService.setValues("mock1", ["1", "2", "3"] as Set<String>)
142+
def mock2LookUp = mySqlLookupService.setValues("mock2", ["4", "5", "6"] as Set<String>)
143+
then:
144+
mock1LookUp.values == ["1", "2", "3"] as Set<String>
145+
mock1LookUp.values == mySqlLookupService.getValues("mock1")
146+
areLookupsEqual(mock1LookUp, mySqlLookupService.get("mock1", true))
147+
mock2LookUp.values == ["4", "5", "6"] as Set<String>
148+
mock2LookUp.values == mySqlLookupService.getValues("mock2")
149+
areLookupsEqual(mock2LookUp, mySqlLookupService.get("mock2", true))
150+
}
151+
}
152+

metacat-metadata-mysql/src/main/java/com/netflix/metacat/metadata/mysql/MySqlLookupService.java

+55-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
package com.netflix.metacat.metadata.mysql;
1515

16+
import com.google.common.base.Joiner;
1617
import com.google.common.collect.Sets;
1718
import com.netflix.metacat.common.server.model.Lookup;
1819
import com.netflix.metacat.common.server.properties.Config;
@@ -22,6 +23,7 @@
2223
import lombok.extern.slf4j.Slf4j;
2324
import org.springframework.dao.EmptyResultDataAccessException;
2425
import org.springframework.jdbc.core.JdbcTemplate;
26+
import org.springframework.jdbc.core.SqlParameterValue;
2527
import org.springframework.jdbc.support.GeneratedKeyHolder;
2628
import org.springframework.jdbc.support.KeyHolder;
2729
import org.springframework.transaction.annotation.Transactional;
@@ -52,6 +54,9 @@ public class MySqlLookupService implements LookupService {
5254
private static final String SQL_INSERT_LOOKUP_VALUE_IF_NOT_EXIST =
5355
"INSERT IGNORE INTO lookup_values (lookup_id, values_string) VALUES (?, ?)";
5456

57+
private static final String SQL_DELETE_LOOKUP_VALUES_IF_NOT_IN =
58+
"delete from lookup_values where lookup_id=? and values_string not in (%s)";
59+
5560
private static final String SQL_GET_LOOKUP_VALUES =
5661
"select values_string value from lookup_values where lookup_id=?";
5762
private static final String SQL_GET_LOOKUP_VALUES_BY_NAME =
@@ -168,6 +173,13 @@ private void insertLookupValuesIfNotExist(final Long id, final Set<String> inser
168173
.collect(Collectors.toList()), new int[]{Types.BIGINT, Types.VARCHAR});
169174
}
170175

176+
private void deleteLookupValuesIfNotIn(final Long id, final Set<String> values) {
177+
jdbcTemplate.update(
178+
String.format(SQL_DELETE_LOOKUP_VALUES_IF_NOT_IN,
179+
"'" + Joiner.on("','").skipNulls().join(values) + "'"),
180+
new SqlParameterValue(Types.BIGINT, id));
181+
}
182+
171183
/**
172184
* findOrCreateLookupByName.
173185
*
@@ -193,6 +205,7 @@ private Lookup findOrCreateLookupByName(final String name, final boolean include
193205
lookup = new Lookup();
194206
lookup.setName(name);
195207
lookup.setId(lookupId);
208+
lookup.setValues(Collections.emptySet());
196209
}
197210
return lookup;
198211
}
@@ -212,13 +225,54 @@ public Lookup addValues(final String name, final Set<String> values, final boole
212225
insertLookupValuesIfNotExist(lookup.getId(), values);
213226
}
214227
if (includeValues) {
215-
lookup.getValues().addAll(values);
228+
if (lookup.getValues() == null || lookup.getValues().isEmpty()) {
229+
lookup.setValues(values);
230+
} else {
231+
lookup.getValues().addAll(values);
232+
}
233+
}
234+
return lookup;
235+
} catch (Exception e) {
236+
final String message = String.format("Failed to set the lookup values for name %s", name);
237+
log.error(message, e);
238+
throw new UserMetadataServiceException(message, e);
239+
}
240+
}
241+
242+
/**
243+
* Saves the lookup value.
244+
*
245+
* @param name lookup name
246+
* @param values multiple values
247+
* @return returns the lookup with the given name.
248+
*/
249+
@Override
250+
public Lookup setValues(final String name, final Set<String> values) {
251+
try {
252+
// For set values, no need to include values from querying rds
253+
// since the values will be the same as the input values
254+
final Lookup lookup = findOrCreateLookupByName(name, false);
255+
if (!values.isEmpty()) {
256+
insertLookupValuesIfNotExist(lookup.getId(), values);
257+
deleteLookupValuesIfNotIn(lookup.getId(), values);
216258
}
259+
lookup.setValues(values);
217260
return lookup;
218261
} catch (Exception e) {
219262
final String message = String.format("Failed to set the lookup values for name %s", name);
220263
log.error(message, e);
221264
throw new UserMetadataServiceException(message, e);
222265
}
223266
}
267+
/**
268+
* Saves the lookup value.
269+
*
270+
* @param name lookup name
271+
* @param value lookup value
272+
* @return returns the lookup with the given name.
273+
*/
274+
@Override
275+
public Lookup setValue(final String name, final String value) {
276+
return setValues(name, Sets.newHashSet(value));
277+
}
224278
}

0 commit comments

Comments
 (0)