Skip to content

Commit c72db67

Browse files
Merge branch 'main' into vault-cli
2 parents 9fefb71 + 1ed48f6 commit c72db67

File tree

17 files changed

+623
-5
lines changed

17 files changed

+623
-5
lines changed

.github/workflows/release-perform.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ jobs:
3838
with:
3939
distribution: goreleaser
4040
version: latest
41-
args: release --rm-dist
41+
args: release
4242
env:
4343
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.goreleaser.yaml

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
version: 2
2+
13
# Make sure to check the documentation at https://goreleaser.com
24
before:
35
hooks:
@@ -13,14 +15,14 @@ builds:
1315
- cli
1416
- provision
1517
- config_mgmt
18+
- timetzdata
1619
env:
1720
- CGO_ENABLED=0
1821
goos:
1922
- linux
2023
- windows
2124
- darwin
22-
tags:
23-
- timetzdata
25+
2426
ldflags:
2527
- "-s -w -X main.appVersion={{ .Version }} -X main.appCommit={{ .Commit }} -X main.appCommitDate={{.CommitDate}}"
2628

@@ -45,7 +47,7 @@ checksum:
4547
name_template: 'checksums.txt'
4648

4749
snapshot:
48-
name_template: "{{ incpatch .Version }}-next"
50+
version_template: "{{ incpatch .Version }}-next"
4951

5052
changelog:
5153
sort: asc

cmd/aem/oak.go

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"github.com/samber/lo"
6+
"github.com/spf13/cobra"
7+
"github.com/wttech/aemc/pkg"
8+
"github.com/wttech/aemc/pkg/common/mapsx"
9+
)
10+
11+
func (c *CLI) oakCmd() *cobra.Command {
12+
cmd := &cobra.Command{
13+
Use: "oak",
14+
Short: "Manages OAK repository",
15+
}
16+
cmd.AddCommand(c.oakIndexCmd())
17+
return cmd
18+
}
19+
20+
func (c *CLI) oakIndexCmd() *cobra.Command {
21+
cmd := &cobra.Command{
22+
Use: "index",
23+
Aliases: []string{"idx"},
24+
Short: "Manage OAK indexes",
25+
}
26+
cmd.AddCommand(c.oakIndexListCmd())
27+
cmd.AddCommand(c.oakIndexReadCmd())
28+
cmd.AddCommand(c.oakIndexReindexCmd())
29+
cmd.AddCommand(c.oakIndexReindexBatchCmd())
30+
return cmd
31+
}
32+
33+
func (c *CLI) oakIndexListCmd() *cobra.Command {
34+
cmd := &cobra.Command{
35+
Use: "list",
36+
Short: "List OAK indexes",
37+
Aliases: []string{"ls"},
38+
Run: func(cmd *cobra.Command, args []string) {
39+
instance, err := c.aem.InstanceManager().One()
40+
if err != nil {
41+
c.Error(err)
42+
return
43+
}
44+
indexes, err := instance.OAK().IndexManager().List()
45+
if err != nil {
46+
c.Error(err)
47+
return
48+
}
49+
c.SetOutput("indexes", indexes)
50+
c.Ok("indexes listed")
51+
},
52+
}
53+
return cmd
54+
}
55+
56+
func (c *CLI) oakIndexReadCmd() *cobra.Command {
57+
cmd := &cobra.Command{
58+
Use: "read",
59+
Short: "Read OAK index details",
60+
Aliases: []string{"get", "find"},
61+
Run: func(cmd *cobra.Command, args []string) {
62+
instance, err := c.aem.InstanceManager().One()
63+
if err != nil {
64+
c.Error(err)
65+
return
66+
}
67+
bundle, err := oakIndexByFlags(cmd, *instance)
68+
if err != nil {
69+
c.Error(err)
70+
return
71+
}
72+
c.SetOutput("index", bundle)
73+
c.Ok("index read")
74+
},
75+
}
76+
oakIndexDefineFlags(cmd)
77+
return cmd
78+
}
79+
80+
func (c *CLI) oakIndexReindexCmd() *cobra.Command {
81+
cmd := &cobra.Command{
82+
Use: "reindex",
83+
Short: "Reindex OAK index",
84+
Run: func(cmd *cobra.Command, args []string) {
85+
instances, err := c.aem.InstanceManager().Some()
86+
if err != nil {
87+
c.Error(err)
88+
return
89+
}
90+
reindexed, err := pkg.InstanceProcess(c.aem, instances, func(instance pkg.Instance) (map[string]any, error) {
91+
index, err := oakIndexByFlags(cmd, instance)
92+
if err != nil {
93+
return nil, err
94+
}
95+
changed, err := index.ReindexWithChanged()
96+
if err != nil {
97+
return nil, err
98+
}
99+
if changed {
100+
if err = index.AwaitNotReindexed(); err != nil {
101+
return nil, err
102+
}
103+
}
104+
return map[string]any{
105+
OutputChanged: changed,
106+
"instance": instance,
107+
"index": index,
108+
}, nil
109+
})
110+
if err != nil {
111+
c.Error(err)
112+
return
113+
}
114+
c.SetOutput("reindexed", reindexed)
115+
if mapsx.SomeHas(reindexed, OutputChanged, true) {
116+
c.Changed("index reindexed")
117+
} else {
118+
c.Ok("index already reindexed (in progress)")
119+
}
120+
},
121+
}
122+
oakIndexDefineFlags(cmd)
123+
return cmd
124+
}
125+
126+
func (c *CLI) oakIndexReindexBatchCmd() *cobra.Command {
127+
cmd := &cobra.Command{
128+
Use: "reindex-batch",
129+
Short: "Reindex OAK indexes in batch",
130+
Run: func(cmd *cobra.Command, args []string) {
131+
instances, err := c.aem.InstanceManager().Some()
132+
if err != nil {
133+
c.Error(err)
134+
return
135+
}
136+
137+
batchId, _ := cmd.Flags().GetString("batch-id")
138+
namePatterns, _ := cmd.Flags().GetStringSlice("name-pattern")
139+
force, _ := cmd.Flags().GetBool("force")
140+
141+
reindexed, err := pkg.InstanceProcess(c.aem, instances, func(instance pkg.Instance) (map[string]any, error) {
142+
indexes, err := instance.OAK().IndexManager().FindByName(namePatterns)
143+
indexNames := lo.Map(indexes, func(i pkg.OAKIndex, _ int) any { return i.Name() })
144+
145+
if force {
146+
if err := instance.OAK().IndexManager().ReindexBatch(indexes); err != nil {
147+
return nil, err
148+
}
149+
return map[string]any{
150+
OutputChanged: true,
151+
"instance": instance,
152+
"indexNames": indexNames,
153+
}, nil
154+
}
155+
156+
changed, err := instance.OAK().IndexManager().ReindexBatchWithChanged(batchId, indexes)
157+
if err != nil {
158+
return nil, err
159+
}
160+
return map[string]any{
161+
OutputChanged: changed,
162+
"instance": instance,
163+
"batchId": batchId,
164+
"indexNames": indexNames,
165+
}, nil
166+
})
167+
if err != nil {
168+
c.Error(err)
169+
return
170+
}
171+
c.SetOutput("reindexed", reindexed)
172+
if mapsx.SomeHas(reindexed, OutputChanged, true) {
173+
c.Changed("indexes batch reindexed")
174+
} else {
175+
c.Ok("indexes batch already reindexed (up-to-date)")
176+
}
177+
},
178+
}
179+
cmd.Flags().StringP("batch-id", "b", "all", "Batch ID")
180+
cmd.Flags().StringSliceP("name-pattern", "n", []string{"*"}, "Index name pattern(s)")
181+
cmd.Flags().BoolP("force", "f", false, "Reindex even if already indexed")
182+
return cmd
183+
}
184+
185+
func oakIndexDefineFlags(cmd *cobra.Command) {
186+
cmd.Flags().String("name", "", "Name")
187+
_ = cmd.MarkFlagRequired("name")
188+
}
189+
190+
func oakIndexByFlags(cmd *cobra.Command, i pkg.Instance) (*pkg.OAKIndex, error) {
191+
name, _ := cmd.Flags().GetString("name")
192+
if len(name) > 0 {
193+
index := i.OAK().IndexManager().New(name)
194+
return &index, nil
195+
}
196+
return nil, fmt.Errorf("flag 'name' is required")
197+
}

cmd/aem/root.go

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ func (c *CLI) rootCmd() *cobra.Command {
2323
cmd.AddCommand(c.configCmd())
2424
cmd.AddCommand(c.instanceCmd())
2525
cmd.AddCommand(c.osgiCmd())
26+
cmd.AddCommand(c.oakCmd())
2627
cmd.AddCommand(c.pkgCmd())
2728
cmd.AddCommand(c.repoCmd())
2829
cmd.AddCommand(c.replCmd())

examples/docker/src/aem/default/etc/aem.yml

+5
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ instance:
197197
# Use checksums to avoid re-installations when snapshot OSGi bundles are unchanged
198198
snapshot_install_skipping: true
199199

200+
# OAK Repository
201+
oak:
202+
index:
203+
await_not_reindexed_timeout: 60m
204+
200205
# Crypto Support
201206
crypto:
202207
key_bundle_symbolic_name: com.adobe.granite.crypto.file

pkg/cfg/defaults.go

+2
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ func (c *Config) setDefaults() {
126126
v.SetDefault("instance.osgi.bundle.snapshot_ignored", false)
127127
v.SetDefault("instance.osgi.bundle.snapshot_patterns", []string{"**/*-SNAPSHOT.jar"})
128128

129+
v.SetDefault("instance.oak.index.await_not_reindexed_timeout", time.Minute*60)
130+
129131
v.SetDefault("instance.ssl.setup_timeout", time.Second*30)
130132

131133
v.SetDefault("instance.crypto.key_bundle_symbolic_name", "com.adobe.granite.crypto.file")

pkg/instance.go

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type Instance struct {
2525
http *HTTP
2626
status *Status
2727
repo *Repo
28+
oak *OAK
2829
osgi *OSGi
2930
sling *Sling
3031
crypto *Crypto
@@ -93,6 +94,10 @@ func (i Instance) OSGI() *OSGi {
9394
return i.osgi
9495
}
9596

97+
func (i Instance) OAK() *OAK {
98+
return i.oak
99+
}
100+
96101
func (i Instance) Sling() *Sling {
97102
return i.sling
98103
}

pkg/instance_manager.go

+1
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ func (im *InstanceManager) New(id, url, user, password string) *Instance {
266266
res.workflowManager = NewWorkflowManager(res)
267267
res.contentManager = NewContentManager(res)
268268
res.osgi = NewOSGi(res)
269+
res.oak = NewOAK(res)
269270
res.sling = NewSling(res)
270271
res.crypto = NewCrypto(res)
271272
res.ssl = NewSSL(res)

pkg/oak.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package pkg
2+
3+
// OAK Facade for managing OAK repository.
4+
type OAK struct {
5+
instance *Instance
6+
7+
indexManager *OAKIndexManager
8+
}
9+
10+
func NewOAK(instance *Instance) *OAK {
11+
return &OAK{
12+
instance: instance,
13+
14+
indexManager: NewOAKIndexManager(instance),
15+
}
16+
}
17+
18+
func (o *OAK) IndexManager() *OAKIndexManager {
19+
return o.indexManager
20+
}

pkg/oak/constants.go

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package oak
2+
3+
const (
4+
IndexListJson = "/oak:index.harray.1.json"
5+
IndexPrimaryType = "oak:QueryIndexDefinition"
6+
)

pkg/oak/index.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package oak
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"github.com/samber/lo"
7+
"github.com/wttech/aemc/pkg/common/fmtx"
8+
"sort"
9+
"strings"
10+
)
11+
12+
type IndexList struct {
13+
List []IndexListItem `json:"__children__"`
14+
}
15+
16+
type IndexListItem struct {
17+
PrimaryType string `json:"jcr:primaryType,omitempty"`
18+
Name string `json:"__name__"`
19+
Type string `json:"type"`
20+
Async any `json:"async"` /* string or []string */
21+
Unique bool `json:"unique"`
22+
IncludedPaths any `json:"includedPaths"` /* string or []string */
23+
ExcludedPaths any `json:"excludedPaths"` /* string or []string */
24+
QueryPaths any `json:"queryPaths"` /* string or []string */
25+
Reindex bool `json:"reindex"`
26+
ReindexCount int `json:"reindexCount"`
27+
EvaluatePathRestrictions bool `json:"evaluatePathRestrictions"`
28+
DeclaringNodeTypes []string `json:"declaringNodeTypes"`
29+
PropertyNames []string `json:"propertyNames"`
30+
Tags []string `json:"tags"`
31+
}
32+
33+
func (il *IndexList) Total() int {
34+
return len(il.List)
35+
}
36+
37+
func (il IndexList) MarshalText() string {
38+
bs := bytes.NewBufferString("")
39+
bs.WriteString(fmtx.TblMap("stats", "stat", "value", map[string]any{
40+
"total": il.Total(),
41+
}))
42+
bs.WriteString("\n")
43+
44+
var indexesSorted []IndexListItem
45+
indexesSorted = append(indexesSorted, il.List...)
46+
sort.SliceStable(indexesSorted, func(i, j int) bool {
47+
return strings.Compare(indexesSorted[i].Name, indexesSorted[j].Name) < 0
48+
})
49+
50+
bs.WriteString(fmtx.TblRows("list", false, []string{"name", "type", "async", "reindex", "reindex count", "tags"}, lo.Map(indexesSorted, func(i IndexListItem, _ int) map[string]any {
51+
return map[string]any{
52+
"name": i.Name,
53+
"type": i.Type,
54+
"async": i.Async,
55+
"reindex": i.Reindex,
56+
"reindex count": i.ReindexCount,
57+
"tags": i.Tags,
58+
}
59+
})))
60+
return bs.String()
61+
}
62+
63+
func (i IndexListItem) String() string {
64+
return fmt.Sprintf("index '%s' (reindex: %v)", i.Name, i.Reindex)
65+
}

0 commit comments

Comments
 (0)