Skip to content

Commit 1d8be81

Browse files
authored
Merge pull request #26 from mcanoy/cache-files
Initial Cache Impl
2 parents b5617d7 + 35a9c36 commit 1d8be81

File tree

12 files changed

+191
-30
lines changed

12 files changed

+191
-30
lines changed

.applier/inventory/group_vars/all.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ build_vars:
1111
OUTPUT_IMAGE_NAME: '{{ app_name }}'
1212
OUTPUT_IMAGE_TAG: latest
1313
PUSH_SECRET: quay-registry-secret
14-
BUILDER_IMAGE_NAME: registry.access.redhat.com/fuse7/fuse-java-openshift
15-
BUILDER_IMAGE_TAG: 1.5
14+
BUILDER_IMAGE_NAME: registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift
15+
BUILDER_IMAGE_TAG: 1.8
1616

1717
pipeline_vars:
1818
PIPELINE_SOURCE_REPOSITORY_URL: https://github.com/rht-labs/open-management-portal-git-api.git

README.md

Lines changed: 90 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,26 @@ If you want to learn more about Quarkus, please visit its website: https://quark
77

88
Prior to running the app, you need to create a **Personal Access Token** linked to your GitLab account.
99

10+
### Local Infinispan (if necessary)
11+
12+
Fire 🔥 up a docker instance of Infinispan to work with the app
13+
14+
```
15+
docker run -it -p 11222:11222 -e USER="omp" -e PASS="omp" infinispan/server:10.1
16+
```
17+
1018
### Running in dev mode
1119

1220
You can run your application in dev mode that enables **live coding** using:
1321
```
22+
export CACHE_CLIENT_INTELLIGENCE=<For mac dev set to BASIC>
23+
export CACHE_USE_AUTH=true
24+
export CONFIG_REPOSITORY_ID =<Git Repo id where the config files are>
25+
export GITLAB_API_URL=<The base url of your git api. ie https://gitlab.com>
1426
export GITLAB_PERSONAL_ACCESS_TOKEN=<GitLab Personal Access Token>
27+
export OMP_LOGGING=DEBUG
28+
export RESIDENCIES_PARENT_REPOSITORIES_ID=<Parent project id where repos will be saved>
29+
export TEMPLATE_REPOSITORY_ID=<Repo where template live>
1530
./mvnw quarkus:dev
1631
```
1732

@@ -27,7 +42,14 @@ source ~/.zshrc
2742

2843
You can run your application using Quarkus profiles using:
2944
```
45+
export CACHE_CLIENT_INTELLIGENCE=<For mac dev set to BASIC>
46+
export CACHE_USE_AUTH=true
47+
export CONFIG_REPOSITORY_ID =<Git Repo id where the config files are>
48+
export GITLAB_API_URL=<The base url of your git api. ie https://gitlab.com>
3049
export GITLAB_PERSONAL_ACCESS_TOKEN=<GitLab Personal Access Token>
50+
export OMP_LOGGING=DEBUG
51+
export RESIDENCIES_PARENT_REPOSITORIES_ID=<Parent project id where repos will be saved>
52+
export TEMPLATE_REPOSITORY_ID=<Repo where template live>
3153
export QUARKUS_PROFILE=<Quarkus profile>
3254
./mvnw clean package
3355
java -jar target/open-management-portal-git-api-*-runner.jar
@@ -51,40 +73,97 @@ You can then execute your binary: `./target/open-management-portal-git-api-1.0.0
5173

5274
If you want to learn more about building native executables, please consult https://quarkus.io/guides/building-native-image-guide .
5375

54-
## Add basic JDG to OCP
76+
## Add Infinispan to OCP via the Infinispan Operator
77+
78+
* Cluster admin probably needed for CRD
79+
80+
### Create secret
81+
82+
Create a secret file named `omp-cache-secret.yaml`. This secret will create an `identities.yaml` file on the cache. Take note of the name that must match the app secret By default the user / pass will be omp / omp as defined in `src/main/resources/application.properties` and the secret below.
83+
84+
```
85+
apiVersion: v1
86+
stringData:
87+
identities.yaml: |+
88+
credentials:
89+
- username: omp
90+
password: omp
91+
- username: operator
92+
password: operator1
93+
kind: Secret
94+
metadata:
95+
labels:
96+
app: infinispan-secret-identities
97+
clusterName: omp-cache
98+
infinispan_cr: omp-cache
99+
name: omp-cache-secret
100+
type: Opaque
101+
```
102+
103+
### Create the Infinispan cluster file
104+
105+
Create a file named infinispan-cluster.yaml
106+
107+
```
108+
apiVersion: infinispan.org/v1
109+
kind: Infinispan
110+
metadata:
111+
name: omp-cache
112+
spec:
113+
replicas: 1
114+
image: infinispan/server:10.1
115+
logging:
116+
categories:
117+
org.infinispan: info
118+
org.jgroups: info
119+
security:
120+
endpointSecretName: omp-cache-secret
121+
```
122+
123+
### Create the Infinispan Operator
124+
125+
Login to OpenShift with the `oc` client and run the following commands
126+
55127
```
56-
oc new-app cache-service \
57-
-p APPLICATION_USER=omp \
58-
-p APPLICATION_PASSWORD=<PASSWORD> \
59-
-p TOTAL_CONTAINER_MEM=4096 \
60-
-p EVICTION_POLICY=reject \
61-
-n <PROJECT_NAME>
128+
# Install Infinispan Operator running these commands
129+
oc apply -f omp-cache-secret.yaml
130+
oc apply -f https://raw.githubusercontent.com/infinispan/infinispan-operator/master/deploy/rbac.yaml
131+
oc apply -f https://raw.githubusercontent.com/infinispan/infinispan-operator/master/deploy/operator.yaml
132+
oc apply -f https://raw.githubusercontent.com/infinispan/infinispan-operator/master/deploy/crd.yaml
133+
134+
# Create an Infinispan Cluster
135+
oc apply -f infinispan-cluster.yaml
62136
```
63137

64138
## Configuration
65139
The preferred place to store non-sensitive data is in the application.properties.
66140

67-
Sensitive fields like git repo location, repository id for residencies, repository id for the config and the GitLab API token are stored in the secrets.
141+
Sensitive fields like the gitlab token and cluster credentials should be stored in a OpenShift secret at a minimum. Other environment specific information should be stored in environmental variables such as repository id for residencies and repository id for the config.
68142
This info is stored in `ocp-s11/labs-test/omp-gitlab-configuration`.
69143

70144
Deployment template will read from the above secret and inject following env variables. These are controlled from application.properties, so if a different env name is needed, change in the application properties file and the deployment template.
71145

72146
* `TEMPLATE_REPOSITORY_ID`
73147
* `RESIDENCIES_PARENT_REPOSITORIES_ID`
74148
* `GITLAB_API_URL`
75-
* `GITLAB_PERSONAL_ACCESS_TOKEN`
149+
* `GITLAB_PERSONAL_ACCESS_TOKEN` (should be secret and a service account)
150+
* `CACHE_SERVICE`
151+
* `CACHE_USER`
152+
* `CACHE_PASS` (should be secret and match the Infinispan operator secret)
153+
* `CACHE_USE_AUTH` set to true
154+
* *
76155

77156
### OpenShift Applier
78157

79-
This project includes an `openshift-applier` inventory. To use it, make sure that you are logged in to the cluster and that you customize the variables in `.applier/inventory/group_vars/all.yml` - namely make sure that `deploy_vars` uses the correct endpoints. Once these are configured, you can deploy the project with:
158+
This section is not guaranteed to be up to date. This project includes an `openshift-applier` inventory. To use it, make sure that you are logged in to the cluster and that you customize the variables in `.applier/inventory/group_vars/all.yml` - namely make sure that `deploy_vars` uses the correct endpoints. Once these are configured, you can deploy the project with:
80159

81160
```bash
82161
cd .applier/
83162
ansible-galaxy install -r requirements.yml --roles-path=roles --force
84163
ansible-playbook apply.yml -i inventory/
85164
```
86165

87-
## Pipeline
166+
## Pipeline (deprecated)
88167

89168
The deployment pipeline is running through a `Jenkinsfile` located in the root folder of the project. This `Jenksinfile` is written in groovy.
90169
The pipeline expects the nexus is available nexus:8080. Make sure that nexus is available and accessible to Jenkins.

src/main/java/com/redhat/labs/cache/GitSyncManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*
2424
* @author faisalmasood
2525
*/
26+
@Deprecated
2627
@Singleton
2728
public class GitSyncManager {
2829

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.redhat.labs.cache;
2+
3+
import javax.enterprise.context.ApplicationScoped;
4+
import javax.inject.Inject;
5+
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
9+
import com.redhat.labs.cache.cacheStore.ResidencyDataCache;
10+
import com.redhat.labs.omp.models.filesmanagement.SingleFileResponse;
11+
12+
import io.quarkus.vertx.ConsumeEvent;
13+
14+
@ApplicationScoped
15+
public class GitSyncService {
16+
public static Logger LOGGER = LoggerFactory.getLogger(GitSyncService.class);
17+
18+
public static final String FILE_CACHE_EVENT = "fileCacheEvent";
19+
20+
@Inject
21+
ResidencyDataCache cache;
22+
23+
@ConsumeEvent(FILE_CACHE_EVENT)
24+
public void consumeTemplate(SingleFileResponse message) {
25+
LOGGER.warn("Caching repo file event:::: {} ", message.cacheKey);
26+
cache.store(message);
27+
}
28+
}

src/main/java/com/redhat/labs/cache/ResidencyDataStore.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public interface ResidencyDataStore {
2222
*/
2323
public void store(String key, ResidencyInformation residencyInformation);
2424

25-
public void store(String key, SingleFileResponse file);
25+
public void store(SingleFileResponse file);
2626

2727
/**
2828
* return NULL if the key is not present
@@ -32,7 +32,7 @@ public interface ResidencyDataStore {
3232
* @param key
3333
* @return
3434
*/
35-
public ResidencyInformation fetch(String key);
35+
public String fetch(String key);
3636

3737
/**
3838
* return all the KEYS stored in the cahe.

src/main/java/com/redhat/labs/cache/cacheStore/ResidencyDataCache.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
import java.util.stream.StreamSupport;
66

77
import javax.enterprise.context.ApplicationScoped;
8+
import javax.enterprise.event.Observes;
89
import javax.inject.Inject;
910

1011
import org.infinispan.client.hotrod.RemoteCache;
1112
import org.infinispan.client.hotrod.RemoteCacheManager;
13+
import org.infinispan.configuration.cache.Configuration;
14+
import org.infinispan.configuration.cache.ConfigurationBuilder;
1215
import org.slf4j.Logger;
1316
import org.slf4j.LoggerFactory;
1417

@@ -17,6 +20,7 @@
1720
import com.redhat.labs.omp.models.filesmanagement.SingleFileResponse;
1821

1922
import io.quarkus.infinispan.client.Remote;
23+
import io.quarkus.runtime.StartupEvent;
2024

2125
/**
2226
* A very simple facade to write the cache data to remote JDG caches.
@@ -28,6 +32,13 @@ public class ResidencyDataCache implements ResidencyDataStore {
2832

2933
public static Logger LOGGER = LoggerFactory.getLogger(ResidencyDataCache.class);
3034

35+
void onStart(@Observes StartupEvent ev) {
36+
LOGGER.debug("On start cache check available ==> {}", cache != null);
37+
if(cache == null) {
38+
createCache();
39+
}
40+
}
41+
3142
@Inject
3243
protected RemoteCacheManager cacheManager;
3344

@@ -44,28 +55,33 @@ public void store(String key, ResidencyInformation residencyInformation) {
4455
}
4556

4657
@Override
47-
public void store(String key, SingleFileResponse file) {
48-
cache.put(key, file);
58+
public void store(SingleFileResponse file) {
59+
cache.put(file.cacheKey, file.fileContent);
4960
}
5061

5162
public void store(String key, String file) {
5263
cache.put(key, file);
5364
}
5465

5566
@Override
56-
public ResidencyInformation fetch(String key) {
57-
return (ResidencyInformation) cache.get(key);
67+
public String fetch(String key) {
68+
return (String) cache.get(key);
5869
}
5970

6071
@Override
6172
public List<String> getAllKeys() {
6273
return StreamSupport
6374
.stream(cache.keySet().spliterator(), true)
6475
.collect(Collectors.toList());
65-
6676
}
6777

6878
public void cleanCache() {
6979
cache.clear();
7080
}
81+
82+
private void createCache() {
83+
LOGGER.info("Create OMP cache");
84+
Configuration config = new ConfigurationBuilder().build();
85+
cache = cacheManager.administration().createCache("omp", config);
86+
}
7187
}

src/main/java/com/redhat/labs/omp/models/filesmanagement/GetMultipleFilesResponse.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@
99
public class GetMultipleFilesResponse implements Serializable {
1010
@JsonbProperty("files")
1111
public List<SingleFileResponse> files;
12+
13+
public String toString() {
14+
return GetMultipleFilesResponse.class.getName() + " :: " + files;
15+
}
1216
}
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
package com.redhat.labs.omp.models.filesmanagement;
22

33
import javax.json.bind.annotation.JsonbProperty;
4-
import java.io.Serializable;
54

65
/**
76
* This class defines the single file content fetchged from Git.
87
*
98
*/
10-
public class SingleFileResponse implements Serializable {
9+
public class SingleFileResponse {
1110

1211
public SingleFileResponse(){
1312

1413
}
1514

1615
public SingleFileResponse(String fileName, String fileContent){
1716
this.fileName = fileName;
18-
1917
this.fileContent = fileContent;
2018
}
2119

@@ -25,7 +23,17 @@ public SingleFileResponse(String fileName, String fileContent){
2523
@JsonbProperty("fileContent")
2624
public String fileContent;
2725

26+
public String cacheKey;
27+
28+
public void setCacheKey(String repoId, String branch) {
29+
cacheKey = String.format("%s:%s:%s", fileName, repoId, branch);
30+
}
31+
2832
public String getFileContent(){
2933
return fileContent;
3034
}
35+
36+
public String toString() {
37+
return String.format("Single FileResponse: name: %s contents: %s", fileName, fileContent);
38+
}
3139
}

src/main/java/com/redhat/labs/omp/resources/CacheResource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ private SingleFileResponse fetchContentFromGit(String fileName) {
8484
GetFileResponse metaFileResponse = gitLabService.getFile(templateRepositoryId, fileName, "master");
8585
String base64Content = metaFileResponse.content;
8686
String content = new String(Base64.getDecoder().decode(base64Content), StandardCharsets.UTF_8);
87-
LOGGER.info("File {} content fetched {}", fileName, content);
87+
LOGGER.debug("File {} content fetched {}", fileName, content);
8888
return new SingleFileResponse(fileName, content);
8989
}
9090
}

0 commit comments

Comments
 (0)