Skip to content

Commit

Permalink
feat: server side config
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkmc committed Jul 13, 2023
1 parent 0c83521 commit 87630e4
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 28 deletions.
31 changes: 23 additions & 8 deletions gql/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"sync"
"time"

"github.com/filecoin-project/boost/node/config"
"github.com/filecoin-project/boost/react"
"github.com/graph-gophers/graphql-go"
"github.com/graph-gophers/graphql-go/relay"
Expand All @@ -22,14 +23,22 @@ import (
var log = logging.Logger("gql")

type Server struct {
resolver *resolver
bstore BlockGetter
srv *http.Server
wg sync.WaitGroup
resolver *resolver
bstore BlockGetter
cfgHandler http.Handler
srv *http.Server
wg sync.WaitGroup
}

func NewServer(resolver *resolver, bstore BlockGetter) *Server {
return &Server{resolver: resolver, bstore: bstore}
func NewServer(cfg *config.Boost, resolver *resolver, bstore BlockGetter) *Server {
webCfg := &corsHandler{sub: &webConfigServer{
cfg: webConfig{
Ipni: webConfigIpni{
IndexerHost: cfg.IndexProvider.WebHost,
},
},
}}
return &Server{resolver: resolver, bstore: bstore, cfgHandler: webCfg}
}

//go:embed schema.graphql
Expand All @@ -40,7 +49,7 @@ func (s *Server) Start(ctx context.Context) error {

// Serve React app
mux := http.NewServeMux()
err := serveReactApp(mux)
err := s.serveReactApp(mux)
if err != nil {
return err
}
Expand Down Expand Up @@ -113,7 +122,7 @@ func (f *fsPrefix) Open(name string) (fs.File, error) {
return f.FS.Open(f.prefix + "/" + name)
}

func serveReactApp(mux *http.ServeMux) error {
func (s *Server) serveReactApp(mux *http.ServeMux) error {
// Catch all requests that are not handled by other handlers
urlPath := "/"

Expand Down Expand Up @@ -142,6 +151,12 @@ func serveReactApp(mux *http.ServeMux) error {
reactApp := http.StripPrefix(urlPath, http.FileServer(http.FS(reactFS)))

mux.HandleFunc(urlPath, func(writer http.ResponseWriter, request *http.Request) {
// Handle requests to get server-side config
if request.URL.Path == urlPath+"config.json" {
s.cfgHandler.ServeHTTP(writer, request)
return
}

matchesFile := func() bool {
// Check each file in the react build path for a match against
// the URL path
Expand Down
29 changes: 29 additions & 0 deletions gql/webconfig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package gql

import (
"encoding/json"
"net/http"
)

type webConfigIpni struct {
IndexerHost string
}

type webConfig struct {
Ipni webConfigIpni
}

type webConfigServer struct {
cfg webConfig
}

func (s *webConfigServer) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
bz, err := json.Marshal(&s.cfg)
if err != nil {
writer.Write([]byte("error serving web config: " + err.Error()))
writer.WriteHeader(500)
return
}

writer.Write(bz)
}
2 changes: 2 additions & 0 deletions node/config/def.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ func DefaultBoost() *Boost {
TopicName: "",
PurgeCacheOnStart: false,

WebHost: "cid.contact",

Announce: IndexProviderAnnounceConfig{
AnnounceOverHttp: false,
DirectAnnounceURLs: []string{"https://cid.contact/ingest/announce"},
Expand Down
3 changes: 3 additions & 0 deletions node/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ type IndexProviderConfig struct {
// datastore if any is present.
PurgeCacheOnStart bool

// The network indexer host that the web UI should link to for published announcements
WebHost string

Announce IndexProviderAnnounceConfig

HttpPublisher IndexProviderHttpPublisherConfig
Expand Down
2 changes: 1 addition & 1 deletion node/modules/storageminer.go
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ func NewGraphqlServer(cfg *config.Boost) func(lc fx.Lifecycle, r repo.LockedRepo

resolverCtx, cancel := context.WithCancel(context.Background())
resolver := gql.NewResolver(resolverCtx, cfg, r, h, dealsDB, logsDB, retDB, plDB, fundsDB, fundMgr, storageMgr, spApi, prov, legacyDeals, legacyProv, legacyDT, ps, sa, piecedirectory, publisher, indexProv, idxProvWrapper, fullNode, ssm, mpool)
server := gql.NewServer(resolver, bg)
server := gql.NewServer(cfg, resolver, bg)

lc.Append(fx.Hook{
OnStart: server.Start,
Expand Down
27 changes: 18 additions & 9 deletions react/src/Ipni.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ import {addClassFor} from "./util-ui";
import bezier2Img from "./bootstrap-icons/icons/bezier2.svg";
import {getDealStatus} from "./RetrievalLogDetail";
import closeImg from "./bootstrap-icons/icons/x-circle.svg";
import {getConfig} from "./config"

const basePath = '/ipni'
const indexerHost = 'cid.contact'

function indexerHost() {
const cfg = getConfig()
return cfg.Ipni.IndexerHost
}

export function IpniPage(props) {
return <PageContainer pageType="ipni" title="Network Indexer">
Expand All @@ -48,15 +53,16 @@ function ProviderInfo(props) {

function ProviderIpniInfo({peerId}) {
const [{loading, error, data}, setResp] = useState({ loading: true })
const idxHost = indexerHost()

// When running boost on a local devnet, hard-code the peer ID to
// sofiaminer's peer ID so we get real provider info back from the indexer
if (process.env.NODE_ENV === 'development') {
peerId = '12D3KooWE8yt84RVwW3sFcd6WMjbUdWrZer2YtT4dmtj3dHdahSZ'
}
useEffect(() => {
fetch('https://'+indexerHost+'/providers/'+peerId).then((res) => {
if (res.status != 200) {
fetch('https://'+idxHost+'/providers/'+peerId).then((res) => {
if (res.status !== 200) {
throw Error("Failed to fetch provider info for "+peerId+" with status code "+res.status)
}
return res.json()
Expand All @@ -65,14 +71,14 @@ function ProviderIpniInfo({peerId}) {
}).catch((err) => setResp({ loading: false, error: err }))
}, [])

if (error) return <div>Error: {"Fetching provider info from "+indexerHost+": "+error.message}</div>
if (error) return <div>Error: {"Fetching provider info from "+idxHost+": "+error.message}</div>
if (loading) return <div>Loading...</div>
if (!data) return null

return <div className="ipni-prov-info">
<h3>Provider Indexer Info</h3>
<div className="subtitle">
From <a href={"https://"+indexerHost+"/providers/"+data.Publisher.ID}>{indexerHost} provider record</a>
From <a href={"https://"+idxHost+"/providers/"+data.Publisher.ID}>{idxHost} provider record</a>
</div>
<table>
<tbody>
Expand All @@ -85,7 +91,7 @@ function ProviderIpniInfo({peerId}) {
<td>{data.Publisher.ID}</td>
</tr>
<tr>
<th>Last Advertisement Processed by {indexerHost}</th>
<th>Last Advertisement Processed by {idxHost}</th>
<td>
{data.LastAdvertisement['/']}
&nbsp;
Expand Down Expand Up @@ -325,6 +331,8 @@ function IpniAdDetailFields({adCid}) {

var ad = data.ipniAdvertisement

const idxHost = indexerHost()

return <div>
<table className="ad-fields">
<tbody>
Expand Down Expand Up @@ -354,7 +362,7 @@ function IpniAdDetailFields({adCid}) {
</tr>
<tr>
<th>Provider</th>
<td><a href={'https://'+indexerHost+'/providers/'+ad.Provider}>{ad.Provider}</a></td>
<td><a href={'https://'+idxHost+'/providers/'+ad.Provider}>{ad.Provider}</a></td>
</tr>
<tr>
<th>Addresses</th>
Expand Down Expand Up @@ -474,6 +482,7 @@ export function IpniAdEntries() {
return <div>Loading ...</div>
}

const idxHost = indexerHost()
var entries = data.ipniAdvertisementEntries
return <div className="ad-detail modal" id={params.adCid}>
<div className="content">
Expand All @@ -484,7 +493,7 @@ export function IpniAdEntries() {
<span>Advertisement {'…'+params.adCid.slice(-8)} Entries</span>
</div>
<div className="entries">
{ entries.length == 0 ? (
{ entries.length === 0 ? (
<span>Advertisement {params.adCid} has no entries</span>
) : (
<table>
Expand All @@ -493,7 +502,7 @@ export function IpniAdEntries() {
return <tr>
<td>{i+1}.</td>
<td>
<a href={"https://"+indexerHost+"/multihash/"+entry}>{entry}</a>
<a href={"https://"+idxHost+"/multihash/"+entry}>{entry}</a>
</td>
</tr>
})}
Expand Down
22 changes: 22 additions & 0 deletions react/src/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var config

export async function initConfig() {
var serverEndpoint = window.location.host
var serverHttpEndpoint = window.location.origin

if (process.env.NODE_ENV === 'development') {
serverEndpoint = 'localhost:8080'
serverHttpEndpoint = 'http://' + serverEndpoint
}

const res = await fetch(serverHttpEndpoint+'/config.json')
config = await res.json()
}

export function setConfig(cfg) {
config = cfg
}

export function getConfig() {
return config
}
30 changes: 20 additions & 10 deletions react/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,25 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {initConfig} from './config'

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
function render() {
ReactDOM.render(
<React.StrictMode>
<App/>
</React.StrictMode>,
document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
}

async function start() {
await initConfig()
render()
}

start()

0 comments on commit 87630e4

Please sign in to comment.