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

OAK commands #265

Merged
merged 9 commits into from
Aug 23, 2024
Merged
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
197 changes: 197 additions & 0 deletions cmd/aem/oak.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
package main

import (
"fmt"
"github.com/samber/lo"
"github.com/spf13/cobra"
"github.com/wttech/aemc/pkg"
"github.com/wttech/aemc/pkg/common/mapsx"
)

func (c *CLI) oakCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "oak",
Short: "Manages OAK repository",
}
cmd.AddCommand(c.oakIndexCmd())
return cmd
}

func (c *CLI) oakIndexCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "index",
Aliases: []string{"idx"},
Short: "Manage OAK indexes",
}
cmd.AddCommand(c.oakIndexListCmd())
cmd.AddCommand(c.oakIndexReadCmd())
cmd.AddCommand(c.oakIndexReindexCmd())
cmd.AddCommand(c.oakIndexReindexBatchCmd())
return cmd
}

func (c *CLI) oakIndexListCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "List OAK indexes",
Aliases: []string{"ls"},
Run: func(cmd *cobra.Command, args []string) {
instance, err := c.aem.InstanceManager().One()
if err != nil {
c.Error(err)
return
}
indexes, err := instance.OAK().IndexManager().List()
if err != nil {
c.Error(err)
return
}
c.SetOutput("indexes", indexes)
c.Ok("indexes listed")
},
}
return cmd
}

func (c *CLI) oakIndexReadCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "read",
Short: "Read OAK index details",
Aliases: []string{"get", "find"},
Run: func(cmd *cobra.Command, args []string) {
instance, err := c.aem.InstanceManager().One()
if err != nil {
c.Error(err)
return
}
bundle, err := oakIndexByFlags(cmd, *instance)
if err != nil {
c.Error(err)
return
}
c.SetOutput("index", bundle)
c.Ok("index read")
},
}
oakIndexDefineFlags(cmd)
return cmd
}

func (c *CLI) oakIndexReindexCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "reindex",
Short: "Reindex OAK index",
Run: func(cmd *cobra.Command, args []string) {
instances, err := c.aem.InstanceManager().Some()
if err != nil {
c.Error(err)
return
}
reindexed, err := pkg.InstanceProcess(c.aem, instances, func(instance pkg.Instance) (map[string]any, error) {
index, err := oakIndexByFlags(cmd, instance)
if err != nil {
return nil, err
}
changed, err := index.ReindexWithChanged()
if err != nil {
return nil, err
}
if changed {
if err = index.AwaitNotReindexed(); err != nil {
return nil, err
}
}
return map[string]any{
OutputChanged: changed,
"instance": instance,
"index": index,
}, nil
})
if err != nil {
c.Error(err)
return
}
c.SetOutput("reindexed", reindexed)
if mapsx.SomeHas(reindexed, OutputChanged, true) {
c.Changed("index reindexed")
} else {
c.Ok("index already reindexed (in progress)")
}
},
}
oakIndexDefineFlags(cmd)
return cmd
}

func (c *CLI) oakIndexReindexBatchCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "reindex-batch",
Short: "Reindex OAK indexes in batch",
Run: func(cmd *cobra.Command, args []string) {
instances, err := c.aem.InstanceManager().Some()
if err != nil {
c.Error(err)
return
}

batchId, _ := cmd.Flags().GetString("batch-id")
namePatterns, _ := cmd.Flags().GetStringSlice("name-pattern")
force, _ := cmd.Flags().GetBool("force")

reindexed, err := pkg.InstanceProcess(c.aem, instances, func(instance pkg.Instance) (map[string]any, error) {
indexes, err := instance.OAK().IndexManager().FindByName(namePatterns)
indexNames := lo.Map(indexes, func(i pkg.OAKIndex, _ int) any { return i.Name() })

if force {
if err := instance.OAK().IndexManager().ReindexBatch(indexes); err != nil {
return nil, err
}
return map[string]any{
OutputChanged: true,
"instance": instance,
"indexNames": indexNames,
}, nil
}

changed, err := instance.OAK().IndexManager().ReindexBatchWithChanged(batchId, indexes)
if err != nil {
return nil, err
}
return map[string]any{
OutputChanged: changed,
"instance": instance,
"batchId": batchId,
"indexNames": indexNames,
}, nil
})
if err != nil {
c.Error(err)
return
}
c.SetOutput("reindexed", reindexed)
if mapsx.SomeHas(reindexed, OutputChanged, true) {
c.Changed("indexes batch reindexed")
} else {
c.Ok("indexes batch already reindexed (up-to-date)")
}
},
}
cmd.Flags().StringP("batch-id", "b", "all", "Batch ID")
cmd.Flags().StringSliceP("name-pattern", "n", []string{"*"}, "Index name pattern(s)")
cmd.Flags().BoolP("force", "f", false, "Reindex even if already indexed")
return cmd
}

func oakIndexDefineFlags(cmd *cobra.Command) {
cmd.Flags().String("name", "", "Name")
_ = cmd.MarkFlagRequired("name")
}

func oakIndexByFlags(cmd *cobra.Command, i pkg.Instance) (*pkg.OAKIndex, error) {
name, _ := cmd.Flags().GetString("name")
if len(name) > 0 {
index := i.OAK().IndexManager().New(name)
return &index, nil
}
return nil, fmt.Errorf("flag 'name' is required")
}
1 change: 1 addition & 0 deletions cmd/aem/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func (c *CLI) rootCmd() *cobra.Command {
cmd.AddCommand(c.configCmd())
cmd.AddCommand(c.instanceCmd())
cmd.AddCommand(c.osgiCmd())
cmd.AddCommand(c.oakCmd())
cmd.AddCommand(c.pkgCmd())
cmd.AddCommand(c.repoCmd())
cmd.AddCommand(c.replCmd())
Expand Down
5 changes: 5 additions & 0 deletions examples/docker/src/aem/default/etc/aem.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@ instance:
# Use checksums to avoid re-installations when snapshot OSGi bundles are unchanged
snapshot_install_skipping: true

# OAK Repository
oak:
index:
await_not_reindexed_timeout: 60m

# Crypto Support
crypto:
key_bundle_symbolic_name: com.adobe.granite.crypto.file
Expand Down
2 changes: 2 additions & 0 deletions pkg/cfg/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ func (c *Config) setDefaults() {
v.SetDefault("instance.osgi.bundle.snapshot_ignored", false)
v.SetDefault("instance.osgi.bundle.snapshot_patterns", []string{"**/*-SNAPSHOT.jar"})

v.SetDefault("instance.oak.index.await_not_reindexed_timeout", time.Minute*60)

v.SetDefault("instance.ssl.setup_timeout", time.Second*30)

v.SetDefault("instance.crypto.key_bundle_symbolic_name", "com.adobe.granite.crypto.file")
Expand Down
5 changes: 5 additions & 0 deletions pkg/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Instance struct {
http *HTTP
status *Status
repo *Repo
oak *OAK
osgi *OSGi
sling *Sling
crypto *Crypto
Expand Down Expand Up @@ -93,6 +94,10 @@ func (i Instance) OSGI() *OSGi {
return i.osgi
}

func (i Instance) OAK() *OAK {
return i.oak
}

func (i Instance) Sling() *Sling {
return i.sling
}
Expand Down
1 change: 1 addition & 0 deletions pkg/instance_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ func (im *InstanceManager) New(id, url, user, password string) *Instance {
res.workflowManager = NewWorkflowManager(res)
res.contentManager = NewContentManager(res)
res.osgi = NewOSGi(res)
res.oak = NewOAK(res)
res.sling = NewSling(res)
res.crypto = NewCrypto(res)
res.ssl = NewSSL(res)
Expand Down
20 changes: 20 additions & 0 deletions pkg/oak.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package pkg

// OAK Facade for managing OAK repository.
type OAK struct {
instance *Instance

indexManager *OAKIndexManager
}

func NewOAK(instance *Instance) *OAK {
return &OAK{
instance: instance,

indexManager: NewOAKIndexManager(instance),
}
}

func (o *OAK) IndexManager() *OAKIndexManager {
return o.indexManager
}
6 changes: 6 additions & 0 deletions pkg/oak/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package oak

const (
IndexListJson = "/oak:index.harray.1.json"
IndexPrimaryType = "oak:QueryIndexDefinition"
)
65 changes: 65 additions & 0 deletions pkg/oak/index.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package oak

import (
"bytes"
"fmt"
"github.com/samber/lo"
"github.com/wttech/aemc/pkg/common/fmtx"
"sort"
"strings"
)

type IndexList struct {
List []IndexListItem `json:"__children__"`
}

type IndexListItem struct {
PrimaryType string `json:"jcr:primaryType,omitempty"`
Name string `json:"__name__"`
Type string `json:"type"`
Async any `json:"async"` /* string or []string */
Unique bool `json:"unique"`
IncludedPaths any `json:"includedPaths"` /* string or []string */
ExcludedPaths any `json:"excludedPaths"` /* string or []string */
QueryPaths any `json:"queryPaths"` /* string or []string */
Reindex bool `json:"reindex"`
ReindexCount int `json:"reindexCount"`
EvaluatePathRestrictions bool `json:"evaluatePathRestrictions"`
DeclaringNodeTypes []string `json:"declaringNodeTypes"`
PropertyNames []string `json:"propertyNames"`
Tags []string `json:"tags"`
}

func (il *IndexList) Total() int {
return len(il.List)
}

func (il IndexList) MarshalText() string {
bs := bytes.NewBufferString("")
bs.WriteString(fmtx.TblMap("stats", "stat", "value", map[string]any{
"total": il.Total(),
}))
bs.WriteString("\n")

var indexesSorted []IndexListItem
indexesSorted = append(indexesSorted, il.List...)
sort.SliceStable(indexesSorted, func(i, j int) bool {
return strings.Compare(indexesSorted[i].Name, indexesSorted[j].Name) < 0
})

bs.WriteString(fmtx.TblRows("list", false, []string{"name", "type", "async", "reindex", "reindex count", "tags"}, lo.Map(indexesSorted, func(i IndexListItem, _ int) map[string]any {
return map[string]any{
"name": i.Name,
"type": i.Type,
"async": i.Async,
"reindex": i.Reindex,
"reindex count": i.ReindexCount,
"tags": i.Tags,
}
})))
return bs.String()
}

func (i IndexListItem) String() string {
return fmt.Sprintf("index '%s' (reindex: %v)", i.Name, i.Reindex)
}
Loading
Loading