Skip to content

Commit 30a1553

Browse files
committed
casa-account-v1: implemented logic to retrieve account details from Cassandra
1 parent 5964e0f commit 30a1553

File tree

8 files changed

+225
-155
lines changed

8 files changed

+225
-155
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,5 @@
4141

4242
# gcloud credentials
4343
gcp/gcloud-config.json
44-
casa-account-v1/secure-connect-vino9.zip
44+
**/secure-connect-vino9.zip
4545

casa-account-v1/k8s/envs/local/kustomization.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ patchesJson6902:
1313
- op: add
1414
path: /spec/template/spec/containers/0/env/0
1515
value: { "name": "TRACING_JAEGER_ENDPOINT", "value": "http://jaeger-collector.istio-system:14268/api/traces" }
16+
- op: add
17+
path: /spec/template/spec/containers/0/env/0
18+
value: { "name": "CASSANDRA_INSTANCE", "value": "astra" }
19+
- op: add
20+
path: /spec/template/spec/containers/0/env/0
21+
value: { "name": "CASSANDRA_PASSWORD", "value": "not_real_password" }
1622
1723
# the environment variable name must match application.yml setting
1824
# in order to override it

casa-account-v1/src/main/java/casa/account/v1/CasaAccountServiceImpl.java

Lines changed: 41 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -3,174 +3,74 @@
33
import com.datastax.oss.driver.api.core.CqlSession;
44
import com.datastax.oss.driver.api.core.cql.ResultSet;
55
import com.datastax.oss.driver.api.core.cql.Row;
6+
import com.datastax.oss.driver.api.core.cql.SimpleStatement;
7+
import com.datastax.oss.driver.api.core.data.UdtValue;
8+
import demo.bank.Balance;
69
import demo.bank.CasaAccount;
710
import demo.bank.CasaAccountServiceGrpc;
811
import demo.bank.GetCasaAccountRequest;
12+
import io.grpc.Status;
913
import io.grpc.stub.StreamObserver;
10-
import io.micronaut.context.annotation.Value;
11-
import io.opencensus.exporter.trace.jaeger.JaegerExporterConfiguration;
12-
import io.opencensus.exporter.trace.jaeger.JaegerTraceExporter;
13-
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration;
14-
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter;
15-
import io.opencensus.trace.AttributeValue;
16-
import io.opencensus.trace.Tracing;
17-
import io.opencensus.trace.config.TraceConfig;
18-
import io.opencensus.trace.samplers.Samplers;
1914
import org.slf4j.Logger;
2015
import org.slf4j.LoggerFactory;
2116

22-
import javax.annotation.PostConstruct;
23-
import javax.annotation.PreDestroy;
17+
import javax.inject.Inject;
2418
import javax.inject.Singleton;
25-
import java.io.IOException;
26-
import java.net.InetSocketAddress;
27-
import java.nio.file.Paths;
28-
import java.util.Map;
19+
import java.util.Set;
20+
21+
import static java.util.stream.Collectors.toSet;
2922

3023
@Singleton
3124
public class CasaAccountServiceImpl extends CasaAccountServiceGrpc.CasaAccountServiceImplBase {
3225

3326
private static final Logger logger = LoggerFactory.getLogger(CasaAccountServiceImpl.class);
3427

35-
@Value("${micronaut.application.name}")
36-
private String appName;
37-
38-
@Value("${tracing.jaeger-endpoint:off}")
39-
private String jaegerThriftEndpoint;
40-
41-
@Value("${tracing.use-stackdriver:false}")
42-
private String stackdriverFlag;
43-
44-
@Value("${cassandra.instance:astra}")
45-
private String cassandraInstance;
46-
47-
@Value("${cassandra.username:vino9}")
48-
private String dbUsername;
49-
50-
@Value("${cassandra.password}")
51-
private String dbPassword;
52-
53-
private CqlSession session;
28+
@Inject private CqlSession session;
5429

5530
public void getAccount(GetCasaAccountRequest req, StreamObserver<CasaAccount> responseObserver) {
5631
String accountId = req.getAccountId();
57-
58-
CasaAccount account =
59-
CasaAccount.newBuilder()
60-
.setAccountId(accountId)
61-
.setNickname("dummy-v1")
62-
.setStatus(CasaAccount.Status.DORMANT)
63-
.build();
64-
responseObserver.onNext(account);
32+
retrieveAccountFromDB(accountId, responseObserver);
6533
responseObserver.onCompleted();
66-
67-
logger.info("Retrieving CasaAccount details for {}", accountId);
68-
}
69-
70-
// this will only work if there is only one gRPC service in the application
71-
// it's probably better to move this out to a Factory class
72-
@PostConstruct
73-
public void initialize() {
74-
initializeTracing();
75-
initializeCassandraSession();
7634
}
7735

78-
@PreDestroy
79-
public void cleanup() {
80-
if (this.session != null) {
81-
logger.info("closing CsqlSession");
82-
this.session.close();
83-
}
84-
}
85-
86-
private void initializeCassandraSession() {
87-
CqlSession session;
36+
private void retrieveAccountFromDB(
37+
String accountId, StreamObserver<CasaAccount> responseObserver) {
38+
logger.info("Retrieving CasaAccount details for {}", accountId);
8839

89-
if ("astra".equalsIgnoreCase(cassandraInstance)) {
90-
session =
91-
CqlSession.builder()
92-
.withCloudSecureConnectBundle(Paths.get("secure-connect-vino9.zip"))
93-
.withAuthCredentials(dbUsername, dbPassword)
94-
.withKeyspace("vino9")
95-
.build();
96-
} else {
97-
session =
98-
CqlSession.builder()
99-
.addContactPoint(new InetSocketAddress("127.0.0.1", 9042))
100-
.withKeyspace("bank")
101-
.withLocalDatacenter("Cassandra")
102-
.build();
103-
}
40+
ResultSet rs =
41+
session.execute(
42+
SimpleStatement.builder("SELECT * FROM casa_account WHERE account_id = ?")
43+
.addPositionalValue(accountId)
44+
.build());
10445

105-
ResultSet rs = session.execute("select release_version from system.local");
10646
Row row = rs.one();
107-
String releaseVersion = row.getString("release_version");
108-
109-
this.session = session;
110-
111-
logger.info("connected to cassandra version {}", releaseVersion);
112-
}
113-
114-
private void initializeTracing() {
115-
boolean exporterInitialized = false;
116-
117-
exporterInitialized = initializeStackdriverExporter();
118-
119-
if (!exporterInitialized) {
120-
exporterInitialized = initializeJaegerExporter();
121-
}
122-
123-
if (!exporterInitialized) {
124-
logger.info("no exporter available, tracing not initialized");
47+
if (row == null) {
48+
responseObserver.onError(
49+
Status.INVALID_ARGUMENT.withDescription("casa account not found").asException());
12550
return;
12651
}
12752

128-
TraceConfig traceConfig = Tracing.getTraceConfig();
129-
traceConfig.updateActiveTraceParams(
130-
traceConfig.getActiveTraceParams().toBuilder().setSampler(Samplers.alwaysSample()).build());
131-
}
132-
133-
boolean initializeJaegerExporter() {
134-
if (jaegerThriftEndpoint != null && jaegerThriftEndpoint.startsWith("http")) {
135-
JaegerTraceExporter.createAndRegister(
136-
JaegerExporterConfiguration.builder()
137-
.setServiceName(appName)
138-
.setThriftEndpoint(jaegerThriftEndpoint)
139-
.build());
140-
141-
logger.info("jaeger exporter initialized");
53+
Set<Balance> balances =
54+
row.getSet("balances", UdtValue.class).stream()
55+
.map(
56+
bal ->
57+
Balance.newBuilder()
58+
.setAmount(bal.getFloat("amount"))
59+
.setCreditFlag(bal.getBoolean("credit"))
60+
.setType(Balance.Type.forNumber(bal.getShort("type")))
61+
.build())
62+
.collect(toSet());
14263

143-
return true;
144-
}
145-
146-
return false;
147-
}
148-
149-
boolean isStackdriverEnabled() {
150-
return "yes".equalsIgnoreCase(stackdriverFlag) || "true".equalsIgnoreCase(stackdriverFlag);
151-
}
152-
153-
boolean initializeStackdriverExporter() {
154-
if (!isStackdriverEnabled()) {
155-
return false;
156-
}
157-
158-
Map<String, AttributeValue> attributes =
159-
Map.of(
160-
"service", AttributeValue.stringAttributeValue("casa-account-v1"),
161-
"runtime", AttributeValue.stringAttributeValue(System.getProperty("java.version")));
162-
163-
try {
164-
StackdriverTraceExporter.createAndRegister(
165-
StackdriverTraceConfiguration.builder()
166-
.setProjectId("vino9-276317")
167-
.setFixedAttributes(attributes)
168-
.build());
169-
} catch (IOException e) {
170-
logger.warn("unable to initialize stackdriver exporter", e);
171-
return false;
172-
}
64+
CasaAccount account =
65+
CasaAccount.newBuilder()
66+
.setAccountId(row.getString("account_id"))
67+
.setNickname(row.getString("nickname"))
68+
.setProdCode(row.getString("prod_code"))
69+
.setProdName(row.getString("prod_name"))
70+
.setStatus(CasaAccount.Status.forNumber(0))
71+
.addAllBalances(balances)
72+
.build();
17373

174-
return true;
74+
responseObserver.onNext(account);
17575
}
17676
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package casa.account.v1;
2+
3+
import com.datastax.oss.driver.api.core.CqlSession;
4+
import com.datastax.oss.driver.api.core.cql.ResultSet;
5+
import io.micronaut.context.annotation.Bean;
6+
import io.micronaut.context.annotation.Factory;
7+
import io.micronaut.context.annotation.Value;
8+
import io.opencensus.exporter.trace.jaeger.JaegerExporterConfiguration;
9+
import io.opencensus.exporter.trace.jaeger.JaegerTraceExporter;
10+
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration;
11+
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter;
12+
import io.opencensus.trace.AttributeValue;
13+
import io.opencensus.trace.Tracer;
14+
import io.opencensus.trace.Tracing;
15+
import io.opencensus.trace.config.TraceConfig;
16+
import io.opencensus.trace.samplers.Samplers;
17+
import org.slf4j.Logger;
18+
import org.slf4j.LoggerFactory;
19+
20+
import java.io.IOException;
21+
import java.net.InetSocketAddress;
22+
import java.nio.file.Paths;
23+
import java.util.Map;
24+
25+
// TODO: need a way to destroy cassandra connection during shutdown
26+
27+
@Factory
28+
public class Initializers {
29+
private static final Logger logger = LoggerFactory.getLogger(Initializers.class);
30+
31+
@Value("${micronaut.application.name}")
32+
private String appName;
33+
34+
@Value("${tracing.jaeger-endpoint:off}")
35+
private String jaegerThriftEndpoint;
36+
37+
@Value("${tracing.use-stackdriver:false}")
38+
private String stackdriverFlag;
39+
40+
@Value("${cassandra.instance:astra}")
41+
private String cassandraInstance;
42+
43+
@Value("${cassandra.username:vino9}")
44+
private String dbUsername;
45+
46+
@Value("${cassandra.password:secret}")
47+
private String dbPassword;
48+
49+
@Value("${cassandra.host:localhost}")
50+
private String localCassandraHost;
51+
52+
@Value("${cassandra.host:9042}")
53+
private int localCassandraPort;
54+
55+
56+
@Bean
57+
public CqlSession initializeCassandraSession() {
58+
logger.info("connect to cassandra instance {}", cassandraInstance);
59+
60+
CqlSession session;
61+
if ("astra".equalsIgnoreCase(cassandraInstance)) {
62+
session =
63+
CqlSession.builder()
64+
.withCloudSecureConnectBundle(Paths.get("secure-connect-vino9.zip"))
65+
.withAuthCredentials(dbUsername, dbPassword)
66+
.withKeyspace("vino9")
67+
.build();
68+
} else if ("local".equalsIgnoreCase(cassandraInstance)) {
69+
session =
70+
CqlSession.builder()
71+
.addContactPoint(new InetSocketAddress(localCassandraHost, localCassandraPort))
72+
.withKeyspace("bank")
73+
.withLocalDatacenter("Cassandra")
74+
.build();
75+
} else {
76+
logger.info("cassandra not available");
77+
return null;
78+
}
79+
80+
ResultSet rs = session.execute("select release_version from system.local");
81+
logger.info("connected to cassandra version {}", rs.one().getString("release_version"));
82+
83+
return session;
84+
}
85+
86+
@Bean
87+
public Tracer initializeTracing() {
88+
boolean exporterInitialized = false;
89+
90+
exporterInitialized = initializeStackdriverExporter();
91+
92+
if (!exporterInitialized) {
93+
exporterInitialized = initializeJaegerExporter();
94+
}
95+
96+
if (!exporterInitialized) {
97+
logger.info("no exporter available, tracing not initialized");
98+
}
99+
100+
TraceConfig traceConfig = Tracing.getTraceConfig();
101+
traceConfig.updateActiveTraceParams(
102+
traceConfig.getActiveTraceParams().toBuilder().setSampler(Samplers.alwaysSample()).build());
103+
104+
return Tracing.getTracer();
105+
}
106+
107+
boolean initializeJaegerExporter() {
108+
if (jaegerThriftEndpoint != null && jaegerThriftEndpoint.startsWith("http")) {
109+
JaegerTraceExporter.createAndRegister(
110+
JaegerExporterConfiguration.builder()
111+
.setServiceName(appName)
112+
.setThriftEndpoint(jaegerThriftEndpoint)
113+
.build());
114+
115+
logger.info("jaeger exporter initialized");
116+
117+
return true;
118+
}
119+
120+
return false;
121+
}
122+
123+
boolean isStackdriverEnabled() {
124+
return "yes".equalsIgnoreCase(stackdriverFlag) || "true".equalsIgnoreCase(stackdriverFlag);
125+
}
126+
127+
boolean initializeStackdriverExporter() {
128+
if (!isStackdriverEnabled()) {
129+
return false;
130+
}
131+
132+
Map<String, AttributeValue> attributes =
133+
Map.of(
134+
"service", AttributeValue.stringAttributeValue(appName),
135+
"runtime", AttributeValue.stringAttributeValue(System.getProperty("java.version")));
136+
137+
try {
138+
StackdriverTraceExporter.createAndRegister(
139+
StackdriverTraceConfiguration.builder()
140+
.setProjectId("vino9-276317")
141+
.setFixedAttributes(attributes)
142+
.build());
143+
} catch (IOException e) {
144+
logger.warn("unable to initialize stackdriver exporter", e);
145+
return false;
146+
}
147+
148+
return true;
149+
}
150+
}

casa-account-v1/src/main/jib/.keep

Whitespace-only changes.

casa-account-v1/src/main/resources/application.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ grpc:
99

1010
tracing:
1111
jaeger-endpoint: off
12-
use-stackdriver: false
12+
use-stackdriver: false
13+
14+
cassandra:
15+
instance: local

0 commit comments

Comments
 (0)