#1
Struts has been a favorite Java framework for web apps, but there's no rule that it can't embrace modern NoSQL stores like CouchDB. Whether you're building JSON-driven services, logging systems, or document-based features, CouchDB offers a flexible, HTTP-based datastore that pairs well with Struts. In this guide, we'll focus solely on setting up CouchDB in Struts—covering Docker-based development and Kubernetes-based production setup—while keeping your configuration clean, environment-aware, and secure.

1. Add the Right Dependencies in pom.xml

Let’s start simple. Plug in Struts, CouchDB client support, and Kubernetes integration:
<dependencies>>  <!-- Struts web framework -->
  <dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>${struts.version}</version>
  </dependency>

  <!-- Ektorp or LightCouch for CouchDB -->
  <dependency>
    <groupId>org.ektorp</groupId>
    <artifactId>org.ektorp</artifactId>
    <version>1.4.3</version>
  </dependency>

  <!-- Kubernetes client support (optional) -->
  <dependency>
    <groupId>io.fabric8</groupId>
    <artifactId>kubernetes-client</artifactId>
    <version>${fabric8.version}</version>
  </dependency>
</dependencies>
Here, Ektorp makes CouchDB easy to work with through Java objects, and the Kubernetes dependency becomes helpful for production configurations.

2. Run CouchDB Locally Using Docker

Here's a simple docker-compose.yml for local dev:
version: '3'
services:
  couchdb:
    image: couchdb:3.3
    environment:
      - COUCHDB_USER=devuser
      - COUCHDB_PASSWORD=devpass
    ports:
      - "5984:5984"
Start it up:
docker-compose up -d
Now you have a local CouchDB instance with an admin user, accessible at http://localhost:5984.

3. Create a Development Configuration: couchdb-dev.properties

Add the following under src/main/resources:
couchdb.url=http://localhost:5984
couchdb.user=devuser
couchdb.password=devpass
couchdb.dbname=devdb
Then load and use it in your Struts helper or DAO class:
Properties props = new Properties();
props.load(getClass().getResourceAsStream("/couchdb-dev.properties"));

HttpClient httpClient = new StdHttpClient.Builder()
    .url(props.getProperty("couchdb.url"))
    .username(props.getProperty("couchdb.user"))
    .password(props.getProperty("couchdb.password"))
    .build();

CouchDbInstance dbInstance = new StdCouchDbInstance(httpClient);
CouchDbConnector connector = dbInstance.createConnector(
    props.getProperty("couchdb.dbname"), true);

Map<String, Object> doc = connector.find(Map.class, "exampleDocId");
This gives you a fully working CouchDB setup right in Struts for local development.

4. Prepare Kubernetes for Production

Avoid hardcoding credentials or URLs in production. Instead, rely on Kubernetes resources:
kubectl create secret generic couchdb-secret \
  --from-literal=COUCHDB_USER=produser \
  --from-literal=COUCHDB_PASSWORD=prodpass

kubectl create configmap couchdb-config \
  --from-literal=COUCHDB_URL=http://couchdb-service:5984 \
  --from-literal=COUCHDB_DBNAME=proddb
This ensures secure management of passwords and flexible configuration of service endpoints.

5. Create Production Configuration: couchdb-prod.properties

Add this to your packaged resources:
couchdb.url=${COUCHDB_URL}
couchdb.user=${COUCHDB_USER}
couchdb.password=${COUCHDB_PASSWORD}
couchdb.dbname=${COUCHDB_DBNAME}
At runtime, your Struts app uses environment variables automatically, so there’s no code change required between dev and prod.

6. Kubernetes Deployment Snippet

Include these environment variables in your Pod spec:
env:
  - name: COUCHDB_URL
    valueFrom:
      configMapKeyRef:
        name: couchdb-config
        key: COUCHDB_URL
  - name: COUCHDB_DBNAME
    valueFrom:
      configMapKeyRef:
        name: couchdb-config
        key: COUCHDB_DBNAME
  - name: COUCHDB_USER
    valueFrom:
      secretKeyRef:
        name: couchdb-secret
        key: COUCHDB_USER
  - name: COUCHDB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: couchdb-secret
        key: COUCHDB_PASSWORD
Once deployed, your Struts application will pick up production parameters straight from the environment.

7. Example: Querying a Document in Struts

Here's a Struts action snippet to test connectivity:
public class CouchDbAction extends ActionSupport {
  public String execute() {
    try {
      Properties props = new Properties();
      props.load(getClass().getResourceAsStream("/couchdb-prod.properties"));
      HttpClient client = new StdHttpClient.Builder()
          .url(props.getProperty("couchdb.url"))
          .username(props.getProperty("couchdb.user"))
          .password(props.getProperty("couchdb.password"))
          .build();
      CouchDbInstance instance = new StdCouchDbInstance(client);
      CouchDbConnector db = instance.createConnector(props.getProperty("couchdb.dbname"), true);
      
      // Try to fetch a document
      Map doc = db.find(Map.class, "health-check");
      addActionMessage("Connected! Found doc: " + doc.get("_id"));
      return SUCCESS;
    } catch (Exception e) {
      addActionError("Failed: " + e.getMessage());
      return ERROR;
    }
  }
}
That’s all it takes—your Struts code uses the same DAO logic in both dev and prod environments, relying solely on different property files.

Why This Setup Works

  • Speedy local dev: Docker-first approach means you can test quickly, with minimal overhead.
  • Production security: Kubernetes Secrets store your credentials safely, without exposing them in code.
  • Unified codebase: Your HTTP-based DAO logic works consistently, regardless of environment.
  • Clean config separation: Separate .properties files reduce crossover errors and confusion.
With this approach, your Struts application is ready to work with CouchDB—both in a local dev environment and a production Kubernetes deployment. Enjoy building JSON-rich, document-driven Java apps without the complexity!

image quote pre code