Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix connection url for Oracle and SqlServer #83

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,30 @@ Disable Property: `org.springframework.cloud.bindings.boot.neo4j.enable`
Type: `oracle`
Disable Property: `org.springframework.cloud.bindings.boot.oracle.enable`

| Property | Value |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `spring.datasource.driver-class-name` | `oracle.jdbc.OracleDriver` |
| `spring.datasource.password` | `{password}` |
| `spring.datasource.url` | `{jdbc-url}` or if not set then `jdbc:oracle://{host}:{port}/{database}` (you must have host, port and database set or no mapping will occur) |
| `spring.datasource.username` | `{username}` |
| `spring.r2dbc.url` | `{r2dbc-url}` or if not set then `r2dbc:oracle://{host}:{port}/{database}` (you must have host, port and database set or no mapping will occur) |
| `spring.r2dbc.password` | `{password}` |
| `spring.r2dbc.username` | `{username}` |
| Property | Value |
| ------------------------------------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `spring.datasource.driver-class-name` | `oracle.jdbc.OracleDriver` |
| `spring.datasource.password` | `{password}` |
| `spring.datasource.url` | `{jdbc-url}` or if not set and `{connection-type}` is also not set then `jdbc:oracle:thin:@{host}:{port}:{database}` (you must have host, port and database set or no mapping will occur) |
| `spring.datasource.username` | `{username}` |
| `spring.r2dbc.url` | `{r2dbc-url}` or if not set then `r2dbc:oracle://{host}:{port}/{database}` (you must have host, port and database set or no mapping will occur) |
| `spring.r2dbc.password` | `{password}` |
| `spring.r2dbc.username` | `{username}` |

If `{connection-type}` is equal to `sid`:
| Property | Value |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `spring.datasource.url` | `jdbc:oracle:{driver}:@{host}:{port}:{sid}` (you must have driver, host, port and sid set or no mapping will occur) |

If `{connection-type}` is equal to `service_name`:
| Property | Value |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `spring.datasource.url` | `jdbc:oracle:{driver}:@//{host}:{port}/{service-name}` (you must have driver, host, port and service-name set or no mapping will occur) |

If `{connection-type}` is equal to `tns`:
| Property | Value |
| ------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `spring.datasource.url` | `jdbc:oracle:{driver}:@{tns-name}` (you must have driver and tns-name set or no mapping will occur) |

### PostgreSQL RDBMS
Type: `postgresql`
Expand Down Expand Up @@ -311,7 +326,7 @@ Disable Property: `org.springframework.cloud.bindings.boot.sqlserver.enable`
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `spring.datasource.driver-class-name` | `com.microsoft.sqlserver.jdbc.SQLServerDriver` |
| `spring.datasource.password` | `{password}` |
| `spring.datasource.url` | `jdbc:sqlserver://{host}:{port}/{database}` (you must have host, port and database set or no mapping will occur) |
| `spring.datasource.url` | `jdbc:sqlserver://{host}:{port};databaseName={database}` (you must have host, port and database set or no mapping will occur) |
| `spring.datasource.username` | `{username}` |
| `spring.r2dbc.url` | `{r2dbc-url}` or if not set then `r2dbc:sqlserver://{host}:{port}/{database}` (you must have host, port and database set or no mapping will occur) |
| `spring.r2dbc.password` | `{password}` |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.util.Arrays;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;

Expand All @@ -40,17 +41,26 @@ interface TriFunction<T, U, V, R> {
R apply(T t, U u, V v);
}

interface QuadFunction<T, U, V, W, R> {
R apply(T t, U u, V v, W w);
}

interface Source {
void to(String key);

void toIfAbsent(String key);

void to(String key, Function<String, Object> function);

void to(String key, BiFunction<String, String, Object> function);

void to(String key, TriFunction<String, String, String, Object> function);

void to(String key, QuadFunction<String, String, String, String, Object> function);

Source when(Predicate<Object> predicate);

Source from(String... keys);
}

final class SourceImpl implements Source {
Expand Down Expand Up @@ -88,6 +98,20 @@ public void to(String key, Function<String, Object> function) {
destination.put(key, function.apply(source.get(keys[0])));
}

@Override
public void to(String key, BiFunction<String, String, Object> function) {
if (keys.length != 2) {
throw new IllegalStateException(
String.format("source size %d cannot be consumed as two arguments", keys.length));
}

if (!Arrays.stream(keys).allMatch(source::containsKey)) {
return;
}

destination.put(key, function.apply(source.get(keys[0]), source.get(keys[1])));
}

@Override
public void to(String key, TriFunction<String, String, String, Object> function) {
if (keys.length != 3) {
Expand All @@ -102,6 +126,20 @@ public void to(String key, TriFunction<String, String, String, Object> function)
destination.put(key, function.apply(source.get(keys[0]), source.get(keys[1]), source.get(keys[2])));
}

@Override
public void to(String key, QuadFunction<String, String, String, String, Object> function) {
if (keys.length != 4) {
throw new IllegalStateException(
String.format("source size %d cannot be consumed as four arguments", keys.length));
}

if (!Arrays.stream(keys).allMatch(source::containsKey)) {
return;
}

destination.put(key, function.apply(source.get(keys[0]), source.get(keys[1]), source.get(keys[2]), source.get(keys[3])));
}

@Override
public Source when(Predicate<Object> predicate) {
if (keys.length != 1) {
Expand All @@ -115,6 +153,11 @@ public Source when(Predicate<Object> predicate) {
return new NoopSource();
}
}

@Override
public Source from(String... keys) {
return new SourceImpl(keys);
}
}

final static class NoopSource implements Source {
Expand All @@ -134,15 +177,30 @@ public void to(String key, Function<String, Object> function) {

}

@Override
public void to(String key, BiFunction<String, String, Object> function) {

}

@Override
public void to(String key, TriFunction<String, String, String, Object> function) {

}

@Override
public void to(String key, QuadFunction<String, String, String, String, Object> function) {

}

@Override
public Source when(Predicate<Object> predicate) {
return this;
}

@Override
public Source from(String... keys) {
return this;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,20 @@ public void process(Environment environment, Bindings bindings, Map<String, Obje
//jdbc properties
map.from("username").to("spring.datasource.username");
map.from("password").to("spring.datasource.password");
// default to connection type sid and thin driver
map.from("host", "port", "database").to("spring.datasource.url",
(host, port, database) -> String.format("jdbc:oracle://%s:%s/%s", host, port, database));
(host, port, database) -> String.format("jdbc:oracle:thin:@%s:%s:%s", host, port, database));

// connection type takes precedence
map.from("connection-type").when("sid"::equals)
.from("driver", "host", "port", "sid").to("spring.datasource.url",
(driver, host, port, sid) -> String.format("jdbc:oracle:%s:@%s:%s:%s", driver, host, port, sid));
map.from("connection-type").when("service_name"::equals)
.from("driver", "host", "port", "service-name").to("spring.datasource.url",
(driver, host, port, serviceName) -> String.format("jdbc:oracle:%s:@//%s:%s/%s", driver, host, port, serviceName));
map.from("connection-type").when("tns"::equals)
.from("driver", "tns-name").to("spring.datasource.url",
(driver, tnsName) -> String.format("jdbc:oracle:%s:@%s", driver, tnsName));

// jdbcURL takes precedence
map.from("jdbc-url").to("spring.datasource.url");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void process(Environment environment, Bindings bindings, Map<String, Obje
//jdbc properties
map.from("password").to("spring.datasource.password");
map.from("host", "port", "database").to("spring.datasource.url",
(host, port, database) -> String.format("jdbc:sqlserver://%s:%s/%s", host, port, database));
(host, port, database) -> String.format("jdbc:sqlserver://%s:%s;databaseName=%s", host, port, database));
map.from("username").to("spring.datasource.username");

// jdbcURL takes precedence
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,48 @@ void notPresent() {
}

@Test
@DisplayName("puts if all present")
void allPresent() {
@DisplayName("does not have key")
void notUseOneKey() {
assertThatThrownBy(() -> map.from().to("test-destination-key"))
.isInstanceOf(IllegalStateException.class);
}

@Test
@DisplayName("puts if both present")
void bothPresent() {
source.put("test-source-key-1", "test-source-value-1");
source.put("test-source-key-2", "test-source-value-2");

map.from("test-source-key-1", "test-source-key-2").to("test-destination-key", (a, b) -> {
assertThat(a).isEqualTo("test-source-value-1");
assertThat(b).isEqualTo("test-source-value-2");

return "test-destination-value";
});

assertThat(destination).containsEntry("test-destination-key", "test-destination-value");
}

@Test
@DisplayName("does not put if not both present")
void notBothPresent() {
source.put("test-source-key-1", "test-source-value-1");

map.from("test-source-key-1", "test-source-key-2").to("test-destination-key", (a, b) -> "test-destination-value");

assertThat(destination).doesNotContainKey("test-destination-key");
}

@Test
@DisplayName("does not have two keys")
void notUseTwoKeys() {
assertThatThrownBy(() -> map.from("test-source-key-1").to("test-destination-key", (a, b) -> "test-destination-value"))
.isInstanceOf(IllegalStateException.class);
}

@Test
@DisplayName("puts if all three present")
void allThreePresent() {
source.put("test-source-key-1", "test-source-value-1");
source.put("test-source-key-2", "test-source-value-2");
source.put("test-source-key-3", "test-source-value-3");
Expand All @@ -86,8 +126,8 @@ void allPresent() {
}

@Test
@DisplayName("does not put if not all present")
void notAllPresent() {
@DisplayName("does not put if not all three present")
void notAllThreePresent() {
source.put("test-source-key-1", "test-source-value-1");
source.put("test-source-key-2", "test-source-value-2");

Expand All @@ -96,6 +136,55 @@ void notAllPresent() {
assertThat(destination).doesNotContainKey("test-destination-key");
}

@Test
@DisplayName("does not have three keys")
void notUseThreeKeys() {
assertThatThrownBy(() -> map.from("test-source-key-1", "test-source-key-2").to("test-destination-key", (a, b, c) -> "test-destination-value"))
.isInstanceOf(IllegalStateException.class);
}

@Test
@DisplayName("puts if all four present")
void allFourPresent() {
source.put("test-source-key-1", "test-source-value-1");
source.put("test-source-key-2", "test-source-value-2");
source.put("test-source-key-3", "test-source-value-3");
source.put("test-source-key-4", "test-source-value-4");

map.from("test-source-key-1", "test-source-key-2", "test-source-key-3", "test-source-key-4")
.to("test-destination-key", (a, b, c, d) -> {
assertThat(a).isEqualTo("test-source-value-1");
assertThat(b).isEqualTo("test-source-value-2");
assertThat(c).isEqualTo("test-source-value-3");
assertThat(d).isEqualTo("test-source-value-4");

return "test-destination-value";
});

assertThat(destination).containsEntry("test-destination-key", "test-destination-value");
}

@Test
@DisplayName("does not put if not all four present")
void notAllFourPresent() {
source.put("test-source-key-1", "test-source-value-1");
source.put("test-source-key-2", "test-source-value-2");
source.put("test-source-key-3", "test-source-value-3");

map.from("test-source-key-1", "test-source-key-2", "test-source-key-3", "test-source-key-4")
.to("test-destination-key", (a, b, c, d) -> "test-destination-value");

assertThat(destination).doesNotContainKey("test-destination-key");
}

@Test
@DisplayName("does not have four keys")
void notUseFourKeys() {
assertThatThrownBy(() -> map.from("test-source-key-1", "test-source-key-2", "test-source-key-3")
.to("test-destination-key", (a, b, c, d) -> "test-destination-value"))
.isInstanceOf(IllegalStateException.class);
}

@Nested
class ToIfAbsentTests {
@Test
Expand Down Expand Up @@ -161,6 +250,33 @@ void onlySupportsOneKey() {
.isInstanceOf(IllegalStateException.class);
}

@Test
@DisplayName("create new source when predicate is true")
void newSourceWhenPredicateIsTrue() {
source.put("test-source-key-1", "test-source-value-1");
source.put("test-source-key-2", "test-source-value-2");


map.from("test-source-key-1").when(value -> true)
.from("test-source-key-2").to("test-destination-key");

assertThat(destination).containsEntry("test-destination-key", "test-source-value-2");
}

@Test
@DisplayName("create noop source when predicate is false")
void noopSourceWhenPredicateIsFalse() {
source.put("test-source-key-1", "test-source-value-1");
source.put("test-source-key-2", "test-source-value-2");


map.from("test-source-key-1").when(value -> false)
.from("test-source-key-2").to("test-destination-key");

assertThat(destination).doesNotContainKey("test-destination-key").doesNotContainValue("test-source-value-1")
.doesNotContainValue("test-source-value-2");
}

@Test
@DisplayName("is complete noop when predicate is false")
void falsePredicateIsNoop() {
Expand All @@ -174,6 +290,10 @@ void falsePredicateIsNoop() {
noopSource.to("three", str -> "content");
noopSource.to("four", (a, b, c) -> "content");

MapMapper.Source noopSourceNew = noopSource.from("five");
noopSourceNew.to("six", (a, b) -> "content");
noopSourceNew.to("seven", (a, b, c, d) -> "content");

assertThat(destination).isEmpty();
}

Expand Down
Loading