21 |
22 |
23 |
24 | This site uses Apache Lucene, specifically this thin-wrapper HTTP server over Lucene, to search all Lucene GitHub issues and pull requests. See
25 | the Eating
26 | dog food with Lucene blog post and Jirasearch 2.0 dog food for details. The source code for indexing and searching GitHub issues is here.
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/githubsearch/static/bootstrap/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/bootstrap/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/bootstrap/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/bootstrap/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/autocomplete.css:
--------------------------------------------------------------------------------
1 | #formWrap {
2 | padding:10px; position:absolute; float:left; background-color:#000;
3 | background:rgba(0,0,0,.5); -moz-border-radius:10px;
4 | -webkit-border-radius:10px; border-radius:10px;
5 | }
6 | #messageForm {
7 | width:326px; border:1px solid #666; background-color:#eee;
8 | }
9 | #messageForm fieldset {
10 | padding:0; margin:0; position:relative; border:none;
11 | background-color:#eee;
12 | }
13 | #messageForm legend { visibility:hidden; height:0; }
14 | #messageForm span {
15 | display:block; width:326px; padding:10px 0; margin:0 0 20px;
16 | text-indent:20px; background-color:#bbb;
17 | border-bottom:1px solid #333; font:18px Georgia, Serif; color:#fff;
18 | }
19 | #friends {
20 | width:274px; padding:3px 3px 0; margin:0 auto;
21 | border:1px solid #aaa; background-color:#fff; cursor:text;
22 | }
23 | #messageForm #to {
24 | width:30px; margin:0 0 2px 0; padding:0 0 3px;
25 | position:relative; top:0; float:left; border:none;
26 | }
27 | #messageForm input, #messageForm textarea {
28 | display:block; width:274px; padding:3px; margin:0 auto 20px;
29 | border:1px solid #aaa;
30 | }
31 | #messageForm label {
32 | display:block; margin:20px 0 3px; text-indent:22px;
33 | font:bold 11px Verdana, Sans-serif; color:#666;
34 | }
35 | #messageForm #toLabel { margin-top:0; }
36 | #messageForm button { float:right; margin:0 0 20px 0; }
37 | #messageForm #cancel { margin-right:20px; }
38 | #friends span {
39 | display:block; margin:0 3px 3px 0; padding:3px 20px 4px 8px;
40 | position:relative; float:left; background-color:#eee;
41 | border:1px solid #333; -moz-border-radius:7px;
42 | -webkit-border-radius:7px; border-radius:7px; color:#333;
43 | font:normal 11px Verdana, Sans-serif;
44 | }
45 | #friends span a {
46 | position:absolute; right:8px; top:2px; color:#666;
47 | font:bold 12px Verdana, Sans-serif; text-decoration:none;
48 | }
49 | #friends span a:hover { color:#ff0000; }
50 | .ui-menu .ui-menu-item { white-space:nowrap; padding:0 10px 0 0; }
51 |
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/animated-overlay.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/animated-overlay.gif
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-icons_228ef1_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-icons_228ef1_256x240.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-icons_ef8c08_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-icons_ef8c08_256x240.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-icons_ffd27a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-icons_ffd27a_256x240.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/css/ui-lightness/images/ui-icons_ffffff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/css/ui-lightness/images/ui-icons_ffffff_256x240.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/favicon.ico
--------------------------------------------------------------------------------
/examples/githubsearch/static/img/1star.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/img/1star.gif
--------------------------------------------------------------------------------
/examples/githubsearch/static/img/2star.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/img/2star.gif
--------------------------------------------------------------------------------
/examples/githubsearch/static/img/3star.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/img/3star.gif
--------------------------------------------------------------------------------
/examples/githubsearch/static/img/4star.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/img/4star.gif
--------------------------------------------------------------------------------
/examples/githubsearch/static/img/5star.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/img/5star.gif
--------------------------------------------------------------------------------
/examples/githubsearch/static/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /search.py
3 | Disallow: /moreFacets.py
4 | Disallow: /suggest.py
5 |
--------------------------------------------------------------------------------
/examples/githubsearch/static/select2/select2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/select2/select2.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/select2/select2x2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/select2/select2x2.png
--------------------------------------------------------------------------------
/examples/githubsearch/static/select2/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/githubsearch/static/select2/spinner.gif
--------------------------------------------------------------------------------
/examples/githubsearch/suggest.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | import sys
17 | sys.path.insert(0, '/home/ec2-user/src/github-ui')
18 | import util
19 | import handle
20 |
21 | # Entry point in production:
22 | def application(environ, startResponse):
23 | return util.handleOnePage(environ, startResponse, handle.handleSuggest)
24 |
--------------------------------------------------------------------------------
/examples/jirasearch/.gitignore:
--------------------------------------------------------------------------------
1 | localconstants.py
2 |
--------------------------------------------------------------------------------
/examples/jirasearch/README.txt:
--------------------------------------------------------------------------------
1 | Simple Python scripts that pull Jira issues via the JSON search API,
2 | index them into luceneserver and offer a simple WSGI search UI to
3 | search/facet.
4 |
5 | loadAllJiraIssues.py -- run this once for a full export of all Jira issues
6 |
7 | createDB.py -- makes a local sqlite3 DB from the above issues loaded
8 |
9 | indexJira.py -- indexes all issues (-reindex -delete), and also does nrt build (-nrt)
10 |
11 |
--------------------------------------------------------------------------------
/examples/jirasearch/TODO:
--------------------------------------------------------------------------------
1 | use renderedFields instead? this translates jira markup to HTML
2 |
3 | hmm is point-in-time searcher version not working!
4 |
5 | better handling of renamed issues
6 |
7 | are we getting dup suggestions w/ rename?
8 |
9 | org.this.that is not splitting into tokens!!
10 |
11 | lucene smoke doesn't highlight lucene in suggestions?
12 |
13 | remove isDev/prod/isMike?
14 |
15 | NRT is failing to show new comments?
16 |
17 | grep through production logs for exeptions!
18 |
19 | why does "bens" make bogus suggestions?
20 |
21 | search for 7462 SHOULD have found LUCENE-7174, like it does in production now
22 |
23 | how come number search e.g. 7462 does not highlight the issue title?
24 |
25 | annoyingly, the Jira query process does NOT count a new commit on an issue as updating its timestamp
26 |
27 | is NRT indexer not seeing newly created issues?
28 |
29 | merge the missed issues back into allIssues.txt in /lucenedata
30 |
31 | is there a faster bulk export?
32 | - should i re-do w/ rendering and use html strip char factory to get good final inch highlighting somehow...
--------------------------------------------------------------------------------
/examples/jirasearch/addIssuesToDB.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | import json
17 | import sqlite3
18 | import pickle
19 | import os
20 | import sys
21 | import localconstants
22 | import datetime
23 |
24 | """
25 | Apply a set of issues from an issues.txt file to the sqlite3 DB used by
26 | indexJira.py for NRT updates.
27 | """
28 |
29 | db = sqlite3.connect(localconstants.DB_PATH)
30 | c = db.cursor()
31 | with open(sys.argv[1], 'rb') as f:
32 | while True:
33 | l = f.readline()
34 | if l == b'':
35 | break
36 | i = l.find(b':')
37 | key = l[:i]
38 | value = l[i+1:].strip()
39 | c.execute('REPLACE INTO issues (key, body) VALUES (?, ?)', (key, pickle.dumps(json.loads(value.decode('utf-8')))))
40 | db.commit()
41 |
--------------------------------------------------------------------------------
/examples/jirasearch/createDB.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | import json
17 | import sqlite3
18 | import pickle
19 | import os
20 | import sys
21 | import localconstants
22 | import datetime
23 |
24 | """
25 | One time conversion, to turn allIssues.txt (exported via
26 | loadAllJiraIssues) -> sqlite3 DB used by indexJira.py for NRT updates.
27 | """
28 |
29 | print('Building DB %s...' % localconstants.DB_PATH)
30 |
31 | if os.path.exists(localconstants.DB_PATH):
32 | os.remove(localconstants.DB_PATH)
33 |
34 | db = sqlite3.connect(localconstants.DB_PATH)
35 | c = db.cursor()
36 | c.execute('DROP TABLE IF EXISTS issues')
37 | c.execute('CREATE TABLE IF NOT EXISTS issues (key text PRIMARY KEY, body text)')
38 | c.execute('CREATE UNIQUE INDEX idx_issues_key ON issues(key)')
39 |
40 | c.execute('CREATE TABLE users (login TEXT UNIQUE PRIMARY KEY, pickle BLOB)')
41 | c.execute('CREATE TABLE full_issue (key TEXT UNIQUE PRIMARY KEY, pickle BLOB)')
42 |
43 | with open('/lucenedata/jirasearch/allIssues.20161017.txt', 'rb') as f:
44 | while True:
45 | l = f.readline()
46 | if l == b'':
47 | break
48 | i = l.find(b':')
49 | key = l[:i]
50 | value = l[i+1:].strip()
51 | c.execute('INSERT INTO issues (key, body) VALUES (?, ?)', (key, pickle.dumps(json.loads(value.decode('utf-8')))))
52 | c.execute('CREATE TABLE IF NOT EXISTS lastUpdate (lastUpdate text)')
53 | c.execute('INSERT INTO lastUpdate VALUES (?)', (pickle.dumps(datetime.datetime(year=2016, month=10, day=17)),))
54 | db.commit()
55 |
--------------------------------------------------------------------------------
/examples/jirasearch/dedup.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | """
17 | Silly tool necessary if your one-time run of loadAllJiraIssues.py crashed and you had to restart it and it loaded some duplicate issues into allIssues.txt
18 | """
19 |
20 | with open('allIssues.txt', 'rb') as f, open('allIssues.dedup.txt', 'wb') as fOut:
21 | seen = set()
22 | while True:
23 | l = f.readline()
24 | if l == b'':
25 | break
26 | i = l.find(b':')
27 | key = l[:i]
28 | if key not in seen:
29 | seen.add(key)
30 | fOut.write(l)
31 | else:
32 | print('skip dup %s' % key)
33 |
--------------------------------------------------------------------------------
/examples/jirasearch/list_issues.py:
--------------------------------------------------------------------------------
1 | import sqlite3
2 | import pickle
3 |
4 | DB_PATH = 'github_issues.db'
5 |
6 | db = sqlite3.connect(DB_PATH)
7 | c = db.cursor()
8 |
9 | issues = c.execute('SELECT pickle FROM issues WHERE key NOT IN ("last_update", "page_upto")').fetchall()
10 | count = 0
11 | for issue in issues:
12 | issue, comments, events, reactions, timeline = pickle.loads(issue[0])
13 | print(f'issue {issue["number"]}\n {len(comments)} comments')
14 | count += 1
15 | print(f'{count} issues')
16 |
--------------------------------------------------------------------------------
/examples/jirasearch/moreFacets.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | #import sys
17 | #sys.path.insert(0, '/home/changingbits/src/ui')
18 | import util
19 | import handle
20 |
21 | # Entry point in production:
22 | def application(environ, startResponse):
23 | return util.handleOnePage(environ, startResponse, handle.handleMoreFacets)
24 |
--------------------------------------------------------------------------------
/examples/jirasearch/production/README.md:
--------------------------------------------------------------------------------
1 | Silly scripts to push both UI and Lucene server changes to production
2 | and bounce the servers.
--------------------------------------------------------------------------------
/examples/jirasearch/production/push.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | import traceback
17 | import sys
18 | import time
19 | import urllib.request, urllib.error, urllib.parse
20 | import os
21 | import shutil
22 | import signal
23 | import runServer
24 |
25 | sys.path.insert(0, '..')
26 | import localconstants
27 |
28 | def run(cmd):
29 | if os.system(cmd):
30 | raise RuntimeError('%s failed; cwd=%s' % (cmd, os.getcwd()))
31 |
32 | if len(sys.argv) == 1:
33 | doServer = True
34 | doUI = True
35 | doReindex = False
36 | else:
37 | doServer = False
38 | doUI = False
39 | doReindex = False
40 |
41 | for arg in sys.argv[1:]:
42 | if arg == '-ui':
43 | doUI = True
44 | elif arg == '-server':
45 | doServer = True
46 | elif arg == '-reindex':
47 | doReindex = True
48 | else:
49 | raise RuntimeError('unknown arg %s' % arg)
50 |
51 | #userHost = 'changingbits@web504.webfaction.com'
52 | userHost = 'ec2-user@jirasearch.mikemccandless.com'
53 | #userHost = 'mike@10.17.4.12'
54 | sshIdent = ''
55 | #sshIdent = '-i /home/mike/.ssh/aws_changingbits.pem'
56 |
57 | print()
58 | print('Snapshot')
59 | run('ssh -t %s %s "cd src/jira-ui/production; python3 -u snapshot.py"' % (sshIdent, userHost))
60 |
61 | if doServer:
62 | serverDistPath = '/l/luceneserver/build/luceneserver-%s.zip' % localconstants.LUCENE_SERVER_VERSION
63 | print()
64 | print('Copy %s' % serverDistPath)
65 | run('scp %s %s %s:src/jira-ui' % (sshIdent, serverDistPath, userHost))
66 | run('ssh %s %s "cd src/jira-ui; rm -rf luceneserver; unzip luceneserver-%s.zip; mv luceneserver-%s luceneserver; rm luceneserver-%s.zip"' % (sshIdent, userHost, localconstants.LUCENE_SERVER_VERSION, localconstants.LUCENE_SERVER_VERSION, localconstants.LUCENE_SERVER_VERSION))
67 |
68 | if doUI:
69 | print('Push UI/indexing scripts')
70 | run('scp %s -r ../gitHistory.py ../handle.py ../indexJira.py ../Latin-dont-break-issues.rbbi ../server.py ../moreFacets.py ../search.py ../static ../production ../suggest.py ../util.py %s:src/jira-ui' % (sshIdent, userHost))
71 |
72 | if doReindex:
73 | extra = ' -reindex'
74 | else:
75 | extra = ''
76 |
77 | if doServer:
78 | extra += ' -server'
79 |
80 | print(f'\nnow restart: {extra}')
81 | run('ssh -t %s %s "cd src/jira-ui/production; python3 -u restart.py%s"' % (sshIdent, userHost, extra))
82 |
83 | print()
84 | print('Verify')
85 | while True:
86 | try:
87 | s = urllib.request.urlopen('http://jirasearch.mikemccandless.com/search.py').read().decode('utf-8')
88 | except:
89 | print()
90 | print('Failed to load search.py... will retry:')
91 | traceback.print_exc()
92 | else:
93 | if s.find('Updated') != -1:
94 | print(' success!')
95 | break
96 | elif s.find('isn\'t started: cannot search'):
97 | time.sleep(0.5)
98 | else:
99 | print('GOT %s' % s)
100 | raise RuntimeError('server is not working?')
101 |
--------------------------------------------------------------------------------
/examples/jirasearch/production/restart.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | import time
17 | import urllib.request, urllib.error, urllib.parse
18 | import os
19 | import sys
20 | import shutil
21 | import signal
22 |
23 | sys.path.insert(0, '..')
24 | import localconstants
25 |
26 | PORT = localconstants.SERVER_PORT
27 |
28 | """
29 | Production script to restart Lucene server and the UI.
30 | """
31 |
32 | doReindex = '-reindex' in sys.argv
33 | doServer = '-server' in sys.argv
34 |
35 | def run(cmd):
36 | if os.system(cmd):
37 | raise RuntimeError('%s failed' % cmd)
38 |
39 | if doServer:
40 | print()
41 | print('Kill current runServer process')
42 |
43 | # kill runServer wrapper:
44 | found = False
45 | for line in os.popen('ps auxww | grep runServer.py | grep -v grep | grep -v /bin/sh').readlines():
46 | pid = line.strip().split()[1]
47 | print(' kill server pid %s: %s' % (pid, line.strip()))
48 | if found:
49 | raise RuntimeError('found two pids!')
50 | try:
51 | run('kill -9 %d' % int(pid))
52 | except:
53 | print('FAILED:')
54 | traceback.print_exc()
55 | found = True
56 |
57 | if False and not found:
58 | raise RuntimeError('could not find existing runServer.py process')
59 |
60 | print()
61 | print('Kill current java server process')
62 |
63 | # kill java process
64 | found = False
65 | for line in os.popen('ps auxww | grep java | grep server.Server | grep "ipPort localhost:%s" | grep -v grep | grep -v /bin/sh' % PORT).readlines():
66 | pid = line.strip().split()[1]
67 | print(' kill server pid %s: %s' % (pid, line.strip()))
68 | if found:
69 | raise RuntimeError('found two pids!')
70 | try:
71 | run('kill -9 %d' % int(pid))
72 | except:
73 | print('FAILED:')
74 | traceback.print_exc()
75 | found = True
76 |
77 | if False and not found:
78 | raise RuntimeError('could not find existing java server.Server process')
79 |
80 | print()
81 | print('Start new java server process')
82 |
83 | run('nohup python3 -u runServer.py > %s/luceneserver.log 2>&1 &' % localconstants.LOG_DIR)
84 |
85 | # Wait until server is really ready:
86 | while True:
87 | s = open('%s/luceneserver.log' % localconstants.LOG_DIR, 'rb').read()
88 | if s.find(('listening on').encode('utf-8')) != -1:
89 | break
90 | time.sleep(1.0)
91 |
92 | print()
93 | print('Restart Apache httpd')
94 |
95 | run('sudo apachectl restart')
96 | #run('sudo /etc/rc.d/init.d/httpd restart')
97 |
98 | print()
99 | print('Kill current Indexer')
100 | for line in os.popen('ps auxww | grep python | grep indexJira.py | grep -v grep | grep -v ssh').readlines():
101 | pid = line.strip().split()[1]
102 | print(' kill indexJira process pid %s [%s]' % (pid, line))
103 | try:
104 | run('kill -9 %d' % int(pid))
105 | except:
106 | pass
107 |
108 | if doReindex:
109 | extra = ' -reindex -delete'
110 | else:
111 | extra = ''
112 |
113 | print()
114 | print('Start new Indexer')
115 | os.chdir('..')
116 | run('nohup python3 -u indexJira.py -server localhost:%s -nrt%s > %s/nrt.log 2>&1 &' % (PORT, extra, localconstants.LOG_DIR))
117 |
118 | print()
119 | print('Wait 5 seconds')
120 | time.sleep(5.0)
121 |
--------------------------------------------------------------------------------
/examples/jirasearch/production/restartForever.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 | import datetime
4 |
5 | while True:
6 | try:
7 | mb = float(os.popen('ps axuww | grep org.apache.lucene.server.Server | grep -v grep').read().split()[5])/1024.
8 | except IndexError:
9 | print('FAILED to find server process; retry in 10s')
10 | time.sleep(10.0)
11 | continue
12 |
13 | if mb > 375.0:
14 | print('%s: now restart @ %.1f MB' % (datetime.datetime.now(), mb))
15 | os.system('python3 -u restart.py')
16 |
17 | time.sleep(10.0)
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/jirasearch/production/runServer.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | import threading
17 | import os
18 | import time
19 | import shutil
20 | import subprocess
21 | import sys
22 | import datetime
23 | import signal
24 |
25 | sys.path.insert(0, '..')
26 |
27 | import localconstants
28 |
29 | """
30 | Python wrapper that spawns the Java lucene server process and restarts it if it dies.
31 | """
32 |
33 | LUCENE_SERVER_VERSION = localconstants.LUCENE_SERVER_VERSION
34 |
35 | def readServerOutput(p, port, startupEvent, failureEvent, eachLine):
36 | while True:
37 | l = p.stdout.readline().decode('utf-8')
38 | if l == '':
39 | if not startupEvent.isSet():
40 | failureEvent.set()
41 | startupEvent.set()
42 | raise RuntimeError('Server failed to start')
43 | else:
44 | break
45 | if 'listening on' in l:
46 | startupEvent.set()
47 | if eachLine is None:
48 | print('SVR: %s' % l.rstrip())
49 | else:
50 | eachLine(l.rstrip())
51 |
52 | class RunServer:
53 |
54 | """
55 | Spawns java subprocess to run the Lucene server.
56 | """
57 |
58 | def __init__(self, port, path, eachLine=None):
59 | self.port = port
60 | startupEvent = threading.Event()
61 | failureEvent = threading.Event()
62 |
63 | #VERSION = '4.2.0-ALPHA'
64 | #VERSION = '4.2-SNAPSHOT'
65 |
66 | HEAP = localconstants.HEAP
67 |
68 | # -agentlib:yjpagent=sampling,disablej2ee
69 | cmd = '%s -Xms%s -Xmx%s -Xss228k -cp "../luceneserver/lib/*" org.apache.lucene.server.Server -maxHTTPThreadCount 2 -ipPort localhost:%s -stateDir %s' % (localconstants.JAVA_EXE, HEAP, HEAP, port, localconstants.ROOT_INDICES_PATH)
70 |
71 | print('SERVER CMD: %s' % cmd)
72 |
73 | self.p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
74 |
75 | t = threading.Thread(target=readServerOutput, args=(self.p, port, startupEvent, failureEvent, eachLine))
76 | t.setDaemon(True)
77 | t.start()
78 |
79 | startupEvent.wait()
80 | if failureEvent.isSet():
81 | sys.exit(0)
82 |
83 | def isAlive(self):
84 | return self.p.poll() is None
85 |
86 | def killServer(self):
87 | try:
88 | self.send('shutdown', {})
89 | except:
90 | pass
91 | print('Find server pid to kill...')
92 | for line in os.popen('ps auxww | grep java | grep server.Server | grep "port %s" | grep -v grep' % self.port).readlines():
93 | pid = line.strip().split()[1]
94 | print('Kill server pid %s' % pid)
95 | try:
96 | os.kill(int(pid), signal.SIGKILL)
97 | except:
98 | pass
99 |
100 | if __name__ == '__main__':
101 |
102 | while True:
103 | print()
104 | print('%s: START SERVER' % datetime.datetime.now())
105 | svr = RunServer(localconstants.SERVER_PORT, localconstants.ROOT_INDICES_PATH)
106 |
107 | try:
108 | while True:
109 | time.sleep(.2)
110 | if not svr.isAlive():
111 | print('NOT ALIVE')
112 | break
113 | finally:
114 | svr.killServer()
115 |
116 | time.sleep(1)
117 |
118 |
--------------------------------------------------------------------------------
/examples/jirasearch/production/snapshot.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | import os
17 | import datetime
18 |
19 | """
20 | This runs on the production box and makes a full backup of src/jira-ui in case we need to rollback.
21 | """
22 |
23 | def run(cmd):
24 | if os.system(cmd):
25 | raise RuntimeError('%s failed' % cmd)
26 |
27 | # Take snapshot in case we need to fallback:
28 | os.chdir('../..')
29 | dt = datetime.datetime.now().date()
30 | upto = 0
31 | while True:
32 | if upto == 0:
33 | fileName = '../snapshots/jira-ui.%04d%02d%02d.tar.bz2' % (dt.year, dt.month, dt.day)
34 | else:
35 | fileName = '../snapshots/jira-ui.%04d%02d%02d-%d.tar.bz2' % (dt.year, dt.month, dt.day, upto)
36 | if not os.path.exists(fileName):
37 | print('snapshot to %s cwd=%s' % (fileName, os.getcwd()))
38 | run('tar cjf %s jira-ui' % fileName)
39 | break
40 | upto += 1
41 |
42 |
--------------------------------------------------------------------------------
/examples/jirasearch/search.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | import io
17 | import gzip
18 | import traceback
19 | #import sys
20 | #sys.path.insert(0, '/home/ec2-user/src/ui')
21 | import util
22 | import handle
23 |
24 | # Entry point in production:
25 | def application(environ, startResponse):
26 | return util.handleOnePage(environ, startResponse, handle.handleQuery)
27 |
--------------------------------------------------------------------------------
/examples/jirasearch/static/about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
21 |
22 |
23 |
24 | This site uses Apache Lucene, specifically this thin-wrapper HTTP server over Lucene, to search all Solr, Tika and Infra Jira issues. See
25 | the Eating
26 | dog food with Lucene blog post and Jirasearch 2.0 dog food for details. The source code for indexing and searching Jira issues is here.
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/jirasearch/static/bootstrap/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/bootstrap/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/bootstrap/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/bootstrap/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/autocomplete.css:
--------------------------------------------------------------------------------
1 | #formWrap {
2 | padding:10px; position:absolute; float:left; background-color:#000;
3 | background:rgba(0,0,0,.5); -moz-border-radius:10px;
4 | -webkit-border-radius:10px; border-radius:10px;
5 | }
6 | #messageForm {
7 | width:326px; border:1px solid #666; background-color:#eee;
8 | }
9 | #messageForm fieldset {
10 | padding:0; margin:0; position:relative; border:none;
11 | background-color:#eee;
12 | }
13 | #messageForm legend { visibility:hidden; height:0; }
14 | #messageForm span {
15 | display:block; width:326px; padding:10px 0; margin:0 0 20px;
16 | text-indent:20px; background-color:#bbb;
17 | border-bottom:1px solid #333; font:18px Georgia, Serif; color:#fff;
18 | }
19 | #friends {
20 | width:274px; padding:3px 3px 0; margin:0 auto;
21 | border:1px solid #aaa; background-color:#fff; cursor:text;
22 | }
23 | #messageForm #to {
24 | width:30px; margin:0 0 2px 0; padding:0 0 3px;
25 | position:relative; top:0; float:left; border:none;
26 | }
27 | #messageForm input, #messageForm textarea {
28 | display:block; width:274px; padding:3px; margin:0 auto 20px;
29 | border:1px solid #aaa;
30 | }
31 | #messageForm label {
32 | display:block; margin:20px 0 3px; text-indent:22px;
33 | font:bold 11px Verdana, Sans-serif; color:#666;
34 | }
35 | #messageForm #toLabel { margin-top:0; }
36 | #messageForm button { float:right; margin:0 0 20px 0; }
37 | #messageForm #cancel { margin-right:20px; }
38 | #friends span {
39 | display:block; margin:0 3px 3px 0; padding:3px 20px 4px 8px;
40 | position:relative; float:left; background-color:#eee;
41 | border:1px solid #333; -moz-border-radius:7px;
42 | -webkit-border-radius:7px; border-radius:7px; color:#333;
43 | font:normal 11px Verdana, Sans-serif;
44 | }
45 | #friends span a {
46 | position:absolute; right:8px; top:2px; color:#666;
47 | font:bold 12px Verdana, Sans-serif; text-decoration:none;
48 | }
49 | #friends span a:hover { color:#ff0000; }
50 | .ui-menu .ui-menu-item { white-space:nowrap; padding:0 10px 0 0; }
51 |
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/animated-overlay.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/animated-overlay.gif
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-icons_228ef1_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-icons_228ef1_256x240.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-icons_ef8c08_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-icons_ef8c08_256x240.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-icons_ffd27a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-icons_ffd27a_256x240.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/css/ui-lightness/images/ui-icons_ffffff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/css/ui-lightness/images/ui-icons_ffffff_256x240.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/favicon.ico
--------------------------------------------------------------------------------
/examples/jirasearch/static/img/1star.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/img/1star.gif
--------------------------------------------------------------------------------
/examples/jirasearch/static/img/2star.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/img/2star.gif
--------------------------------------------------------------------------------
/examples/jirasearch/static/img/3star.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/img/3star.gif
--------------------------------------------------------------------------------
/examples/jirasearch/static/img/4star.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/img/4star.gif
--------------------------------------------------------------------------------
/examples/jirasearch/static/img/5star.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/img/5star.gif
--------------------------------------------------------------------------------
/examples/jirasearch/static/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /search.py
3 | Disallow: /moreFacets.py
4 | Disallow: /suggest.py
5 |
--------------------------------------------------------------------------------
/examples/jirasearch/static/select2/select2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/select2/select2.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/select2/select2x2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/select2/select2x2.png
--------------------------------------------------------------------------------
/examples/jirasearch/static/select2/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikemccand/luceneserver/e573ed76f6579824d18bcba7e245e6d860947d0f/examples/jirasearch/static/select2/spinner.gif
--------------------------------------------------------------------------------
/examples/jirasearch/suggest.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | #import sys
17 | #sys.path.insert(0, '/home/changingbits/src/ui')
18 | import util
19 | import handle
20 |
21 | # Entry point in production:
22 | def application(environ, startResponse):
23 | return util.handleOnePage(environ, startResponse, handle.handleSuggest)
24 |
--------------------------------------------------------------------------------
/scripts/esJSONToLuceneServerJSON.py:
--------------------------------------------------------------------------------
1 | import struct
2 | import json
3 | import sys
4 |
5 | class BlockedFileReader:
6 |
7 | def __init__(self, fileName):
8 | self.f = open(fileName, 'rb')
9 | self.pending = self.read()
10 | self.pendingUpto = 0
11 |
12 | def __enter__(self):
13 | return self
14 |
15 | def __exit__(self, exc_type, exc_value, traceback):
16 | self.f.close()
17 |
18 | def read(self):
19 | b = self.f.read(8)
20 | if len(b) == 0:
21 | return None
22 | count, length = struct.unpack('ii', b)
23 | data = self.f.read(length)
24 | return data
25 |
26 | def readline(self):
27 | while True:
28 | i = self.pending.find(b'\n', self.pendingUpto)
29 | if i == -1:
30 | self.pending = self.pending[self.pendingUpto:]
31 | self.pendingUpto = 0
32 | inc = self.read()
33 | if inc is None:
34 | if len(self.pending) > 0:
35 | result = self.pending
36 | self.pending = b''
37 | return result
38 | else:
39 | return None
40 | else:
41 | self.pending += inc
42 | else:
43 | result = self.pending[self.pendingUpto:i+1]
44 | self.pendingUpto = i+1
45 | return result
46 |
47 | class BlockedFileWriter:
48 |
49 | def __init__(self, fileName, minBlockBytes):
50 | self.f = open(fileName, 'wb')
51 | self.minBlockBytes = minBlockBytes
52 | self.pending = []
53 | self.pendingLength = 0
54 |
55 | def __enter__(self):
56 | return self
57 |
58 | def __exit__(self, exc_type, exc_value, traceback):
59 | self.f.close()
60 |
61 | def add(self, b):
62 | if b'\n' in b:
63 | raise RuntimeError('entry cannot contain newline')
64 | self.pending.append(b)
65 | self.pendingLength += len(b)+1
66 | if self.pendingLength > self.minBlockBytes:
67 | self.flush()
68 |
69 | def flush(self):
70 | self.f.write(struct.pack('ii', len(self.pending), self.pendingLength))
71 | self.f.write(b'\n'.join(self.pending) + b'\n')
72 | self.pending = []
73 | self.pendingLength = 0
74 |
75 | def close(self):
76 | if len(self.pending) > 0:
77 | self.flush()
78 | self.f.close()
79 |
80 | srcFile, destFile = sys.argv[1:3]
81 |
82 | with BlockedFileReader(srcFile) as fIn, BlockedFileWriter(destFile, 1024*1024) as fOut:
83 | while True:
84 | if fIn.readline() is None:
85 | break
86 | s = fIn.readline()
87 | #print("add %s" % s)
88 | fOut.add(s[:-1])
89 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/Connection.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.io.BufferedOutputStream;
21 | import java.io.Closeable;
22 | import java.io.IOException;
23 | import java.io.InputStream;
24 | import java.net.InetSocketAddress;
25 | import java.net.Socket;
26 |
27 | import org.apache.lucene.store.DataInput;
28 | import org.apache.lucene.store.DataOutput;
29 | import org.apache.lucene.store.InputStreamDataInput;
30 | import org.apache.lucene.store.OutputStreamDataOutput;
31 |
32 | /** Simple point-to-point TCP connection */
33 | public class Connection implements Closeable {
34 | public final DataInput in;
35 | public final DataOutput out;
36 | public final InputStream sockIn;
37 | public final BufferedOutputStream bos;
38 | public final Socket s;
39 | public final InetSocketAddress destAddress;
40 | public long lastKeepAliveNS = System.nanoTime();
41 |
42 | public Connection(InetSocketAddress address) throws IOException {
43 | this.destAddress = address;
44 | System.out.println("CONNECT: " + address);
45 | this.s = new Socket(address.getAddress(), address.getPort());
46 | this.sockIn = s.getInputStream();
47 | this.in = new InputStreamDataInput(sockIn);
48 | // nocommit don't use BOS (it's trappy: you can forget to flush); do our own buffering above so the protocol is explicit:
49 | this.bos = new BufferedOutputStream(s.getOutputStream());
50 | this.out = new OutputStreamDataOutput(bos);
51 | }
52 |
53 | public void flush() throws IOException {
54 | bos.flush();
55 | }
56 |
57 | @Override
58 | public void close() throws IOException {
59 | s.close();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/Constants.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.util.regex.Pattern;
21 |
22 | /** Static constants. */
23 | public class Constants {
24 | private Constants() {
25 | }
26 |
27 | // nocommit can we nuke this hack now?
28 | /** Used to join multi-valued fields. */
29 | public static final char INFORMATION_SEP = '\u001f';
30 |
31 | /** Regexp version of {@link #INFORMATION_SEP}. */
32 | public static final String INFORMATION_SEP_REGEX = Pattern.quote(Character.toString(INFORMATION_SEP));
33 | }
34 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/DirectoryFactory.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server;
2 |
3 | /**
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.io.IOException;
21 | import java.lang.reflect.Constructor;
22 | import java.lang.reflect.InvocationTargetException;
23 | import java.nio.file.Path;
24 |
25 | //import org.apache.lucene.store.AsyncFSDirectory;
26 | import org.apache.lucene.store.Directory;
27 | import org.apache.lucene.store.FSDirectory;
28 | import org.apache.lucene.store.MMapDirectory;
29 | import org.apache.lucene.store.NIOFSDirectory;
30 |
31 | /** A factory to open a {@link Directory} from a provided
32 | * filesystem path. */
33 | public abstract class DirectoryFactory {
34 |
35 | /** Sole constructor. */
36 | public DirectoryFactory() {
37 | }
38 |
39 | /** Open a new {@link Directory} at the specified path. */
40 | public abstract Directory open(Path path) throws IOException;
41 |
42 | /** Returns an instance, using the specified
43 | * implementation {FSDirectory, MMapDirectory,
44 | * NIOFSDirectory}. */
45 | public static DirectoryFactory get(final String dirImpl) {
46 | if (dirImpl.equals("FSDirectory")) {
47 | return new DirectoryFactory() {
48 | @Override
49 | public Directory open(Path path) throws IOException {
50 | return FSDirectory.open(path);
51 | }
52 | };
53 | } else if (dirImpl.equals("MMapDirectory")) {
54 | return new DirectoryFactory() {
55 | @Override
56 | public Directory open(Path path) throws IOException {
57 | return new MMapDirectory(path);
58 | }
59 | };
60 | } else if (dirImpl.equals("NIOFSDirectory")) {
61 | return new DirectoryFactory() {
62 | @Override
63 | public Directory open(Path path) throws IOException {
64 | return new NIOFSDirectory(path);
65 | }
66 | };
67 | } else {
68 | final Class extends Directory> dirClass;
69 | try {
70 | dirClass = Class.forName(dirImpl).asSubclass(Directory.class);
71 | } catch (ClassNotFoundException cnfe) {
72 | throw new IllegalArgumentException("could not locate Directory sub-class \"" + dirImpl + "\"; verify CLASSPATH");
73 | }
74 | final Constructor extends Directory> ctor;
75 | try {
76 | ctor = dirClass.getConstructor(Path.class);
77 | } catch (NoSuchMethodException nsme) {
78 | throw new IllegalArgumentException("class \"" + dirImpl + "\" does not have a constructor taking a single Path argument");
79 | }
80 |
81 | return new DirectoryFactory() {
82 | @Override
83 | public Directory open(Path path) throws IOException {
84 | try {
85 | return ctor.newInstance(path);
86 | } catch (InstantiationException ie) {
87 | throw new RuntimeException("failed to instantiate directory class \"" + dirImpl + "\" on path=\"" + path + "\"", ie);
88 | } catch (InvocationTargetException ite) {
89 | throw new RuntimeException("failed to instantiate directory class \"" + dirImpl + "\" on path=\"" + path + "\"", ite);
90 | } catch (IllegalAccessException iae) {
91 | throw new RuntimeException("failed to instantiate directory class \"" + dirImpl + "\" on path=\"" + path + "\"", iae);
92 | }
93 | }
94 | };
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/FieldDefBindings.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.util.Map;
21 |
22 | import org.apache.lucene.expressions.Bindings;
23 | import org.apache.lucene.index.DocValuesType;
24 | import org.apache.lucene.search.DoubleValuesSource;
25 |
26 | /** Implements {@link Bindings} on top of the registered
27 | * fields. */
28 | public final class FieldDefBindings extends Bindings {
29 |
30 | private final Map fields;
31 |
32 | /** Sole constructor. */
33 | public FieldDefBindings(Map fields) {
34 | this.fields = fields;
35 | }
36 |
37 | @Override
38 | public DoubleValuesSource getDoubleValuesSource(String name) {
39 | if (name.equals("_score")) {
40 | return DoubleValuesSource.SCORES;
41 | }
42 | FieldDef fd = fields.get(name);
43 | if (fd == null) {
44 | throw new IllegalArgumentException("Invalid reference '" + name + "'");
45 | }
46 | if (fd.valueType == FieldDef.FieldValueType.VIRTUAL) {
47 | return fd.valueSource;
48 | } else if (fd.fieldType != null && fd.fieldType.docValuesType() == DocValuesType.NUMERIC) {
49 | if (fd.valueType == FieldDef.FieldValueType.INT) {
50 | return DoubleValuesSource.fromIntField(name);
51 | } else if (fd.valueType == FieldDef.FieldValueType.FLOAT) {
52 | return DoubleValuesSource.fromFloatField(name);
53 | } else if (fd.valueType == FieldDef.FieldValueType.LONG) {
54 | return DoubleValuesSource.fromLongField(name);
55 | } else if (fd.valueType == FieldDef.FieldValueType.DOUBLE) {
56 | return DoubleValuesSource.fromDoubleField(name);
57 | } else {
58 | assert false: "unknown numeric field type: " + fd.valueType;
59 | return null;
60 | }
61 | } else {
62 | throw new IllegalArgumentException("Field \'" + name + "\' cannot be used in an expression: it was not registered with sort=true");
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/FinishRequest.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | // nocommit: javadocs seem outdated
21 |
22 | /** Returned from {@code Handler#finish} to make actual
23 | * changes from the request. We do this two-step
24 | * process so that we can fail if there are unhandled
25 | * params, without having made any changes to the index. */
26 | public interface FinishRequest {
27 |
28 | /** Perform the actual work of the request. */
29 | public String finish() throws Exception;
30 | }
31 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/MyIndexSearcher.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.io.IOException;
21 | import java.util.List;
22 |
23 | import org.apache.lucene.index.IndexReader;
24 | import org.apache.lucene.index.LeafReaderContext;
25 | import org.apache.lucene.search.BulkScorer;
26 | import org.apache.lucene.search.CollectionTerminatedException;
27 | import org.apache.lucene.search.Collector;
28 | import org.apache.lucene.search.DocIdSetIterator;
29 | import org.apache.lucene.search.IndexSearcher;
30 | import org.apache.lucene.search.LeafCollector;
31 | import org.apache.lucene.search.Query;
32 | import org.apache.lucene.search.Scorer;
33 | import org.apache.lucene.search.Weight;
34 | import org.apache.lucene.search.join.ToParentBlockJoinQuery;
35 | import org.apache.lucene.util.Bits;
36 |
37 | /** This is sadly necessary because for ToParentBlockJoinQuery we must invoke .scorer not .bulkScorer, yet for DrillSideways we must do
38 | * exactly the opposite! */
39 |
40 | public class MyIndexSearcher extends IndexSearcher {
41 | public MyIndexSearcher(IndexReader reader) {
42 | super(reader);
43 | }
44 |
45 | @Override
46 | protected void search(List leaves, Weight weight, Collector collector) throws IOException {
47 |
48 | // nocommit -- removeme? do we still rely on this Scorer not BulkScorer / getChildren?
49 | for (LeafReaderContext ctx : leaves) { // search each subreader
50 | // we force the use of Scorer (not BulkScorer) to make sure
51 | // that the scorer passed to LeafCollector.setScorer supports
52 | // Scorer.getChildren -- messy messy! maybe broken now?
53 | final LeafCollector leafCollector = collector.getLeafCollector(ctx);
54 | if (weight.getQuery().toString().contains("DrillSidewaysQuery")) {
55 | BulkScorer scorer = weight.bulkScorer(ctx);
56 | if (scorer != null) {
57 | try {
58 | scorer.score(leafCollector, ctx.reader().getLiveDocs());
59 | } catch (CollectionTerminatedException e) {
60 | // collection was terminated prematurely
61 | // continue with the following leaf
62 | }
63 | }
64 | } else {
65 | Scorer scorer = weight.scorer(ctx);
66 | if (scorer != null) {
67 | leafCollector.setScorer(scorer);
68 | final Bits liveDocs = ctx.reader().getLiveDocs();
69 | final DocIdSetIterator it = scorer.iterator();
70 | for (int doc = it.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; doc = it.nextDoc()) {
71 | if (liveDocs == null || liveDocs.get(doc)) {
72 | leafCollector.collect(doc);
73 | }
74 | }
75 | }
76 | }
77 |
78 | // Note: this is called if collection ran successfully, including the above special cases of
79 | // CollectionTerminatedException and TimeExceededException, but no other exception.
80 | leafCollector.finish();
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/PreHandle.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import org.apache.lucene.server.params.Request;
21 |
22 | // nocommit: outdated javadocs?
23 |
24 | /** A callback that can modify a request before the main
25 | * {@code Handler} sees it. Plugins can use this to
26 | * pre-process requests. */
27 |
28 | public interface PreHandle {
29 |
30 | /** Invoked before the selected handler runs. */
31 | public void invoke(Request request) throws Exception;
32 | }
33 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/QueryID.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.util.Arrays;
21 |
22 | import org.apache.lucene.util.StringHelper;
23 |
24 | /** Uniquely identifies a query; just a thin wrapper around a byte[] so we can define equals/hashCode. */
25 |
26 | public class QueryID {
27 |
28 | public final byte[] id;
29 |
30 | public QueryID() {
31 | this(StringHelper.randomId());
32 | }
33 |
34 | public QueryID(byte[] id) {
35 | this.id = id;
36 | }
37 |
38 | @Override
39 | public boolean equals(Object other) {
40 | if (other instanceof QueryID) {
41 | return Arrays.equals(((QueryID) other).id, id);
42 | } else {
43 | return false;
44 | }
45 | }
46 |
47 | @Override
48 | public int hashCode() {
49 | return Arrays.hashCode(id);
50 | }
51 |
52 | @Override
53 | public String toString() {
54 | return StringHelper.idToString(id);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/RemoteNodeConnection.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.io.Closeable;
21 | import java.io.IOException;
22 |
23 | /** Persistent connections to other nodes in the cluster for us to send commands to them */
24 | public final class RemoteNodeConnection implements Closeable {
25 | public final byte[] nodeID;
26 | public final Connection c;
27 |
28 | public RemoteNodeConnection(byte[] nodeID, Connection c) {
29 | this.nodeID = nodeID;
30 | this.c = c;
31 | }
32 |
33 | @Override
34 | public void close() throws IOException {
35 | c.close();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/ServerCodec.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import org.apache.lucene.codecs.Codec;
21 | import org.apache.lucene.codecs.DocValuesFormat;
22 | import org.apache.lucene.codecs.PostingsFormat;
23 | import org.apache.lucene.codecs.lucene95.Lucene95Codec;
24 |
25 | /** Implements per-index {@link Codec}. */
26 |
27 | public class ServerCodec extends Lucene95Codec {
28 |
29 | public final static String DEFAULT_POSTINGS_FORMAT = "Lucene90";
30 | public final static String DEFAULT_DOC_VALUES_FORMAT = "Lucene90";
31 |
32 | private final IndexState state;
33 | // nocommit expose compression control
34 |
35 | /** Sole constructor. */
36 | public ServerCodec(IndexState state) {
37 | this.state = state;
38 | }
39 |
40 | @Override
41 | public PostingsFormat getPostingsFormatForField(String field) {
42 | String pf;
43 | try {
44 | pf = state.getField(field).postingsFormat;
45 | } catch (IllegalArgumentException iae) {
46 | // The indexed facets field will have drill-downs,
47 | // which will pull the postings format:
48 | if (state.internalFacetFieldNames.contains(field)) {
49 | return super.getPostingsFormatForField(field);
50 | } else {
51 | throw iae;
52 | }
53 | }
54 | return PostingsFormat.forName(pf);
55 | }
56 |
57 | @Override
58 | public DocValuesFormat getDocValuesFormatForField(String field) {
59 | String dvf;
60 | try {
61 | dvf = state.getField(field).docValuesFormat;
62 | } catch (IllegalArgumentException iae) {
63 | if (state.internalFacetFieldNames.contains(field)) {
64 | return super.getDocValuesFormatForField(field);
65 | } else {
66 | throw iae;
67 | }
68 | }
69 | return DocValuesFormat.forName(dvf);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/WholeMVJSONPassageFormatter.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import org.apache.lucene.search.uhighlight.Passage;
21 | import org.apache.lucene.search.uhighlight.PassageFormatter;
22 | import net.minidev.json.JSONArray;
23 | import net.minidev.json.JSONObject;
24 |
25 | /** From a multi-valued field (indexed with the values
26 | * joined with INFO_SEP), highlight each value entirely. */
27 | public class WholeMVJSONPassageFormatter extends PassageFormatter {
28 |
29 | private final int offsetGap;
30 |
31 | /** Create this, with the specified offsetGap. */
32 | public WholeMVJSONPassageFormatter(int offsetGap) {
33 | this.offsetGap = offsetGap;
34 | }
35 |
36 | /** Carefully finds the field boundaries
37 | * (INFORMATION_SEPARATOR) in the content and builds a
38 | * JSONArray so that each original field value is
39 | * separated and highlighted. */
40 | @Override
41 | public JSONArray format(Passage[] passages, String content) {
42 |
43 | // Caller must use WholeBreakIterator:
44 | assert passages.length == 1;
45 | Passage passage = passages[0];
46 |
47 | String[] chunks = content.split(Constants.INFORMATION_SEP_REGEX);
48 | JSONArray result = new JSONArray();
49 | int matchUpto = 0;
50 | int charOffset = 0;
51 | for(String chunk : chunks) {
52 | JSONArray part = new JSONArray();
53 | result.add(part);
54 | int pos = 0;
55 | int posEnd = chunk.length();
56 | while (matchUpto < passage.getNumMatches()) {
57 | int start = passage.getMatchStarts()[matchUpto] - charOffset;
58 | if (start >= posEnd) {
59 | break;
60 | }
61 | if (start > pos) {
62 | part.add(chunk.substring(pos, start));
63 | pos = start;
64 | }
65 | JSONObject match = new JSONObject();
66 | part.add(match);
67 | int end = passage.getMatchEnds()[matchUpto] - charOffset;
68 | match.put("text", chunk.substring(start, end));
69 | match.put("term", passage.getMatchTerms()[matchUpto].utf8ToString());
70 | pos = end;
71 | matchUpto++;
72 | }
73 | if (pos < chunk.length()) {
74 | part.add(chunk.substring(pos));
75 | pos = chunk.length();
76 | }
77 |
78 | // nocommit we always join w/ INFO_SEP ... so it
79 | //should just be 1?
80 | //charOffset += chunk.length()+offsetGap;
81 | charOffset += chunk.length()+1;
82 | }
83 |
84 | return result;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/handlers/AddDocumentsHandler.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server.handlers;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.io.StringReader;
21 | import java.util.List;
22 | import java.util.Map;
23 |
24 | import org.apache.lucene.server.FinishRequest;
25 | import org.apache.lucene.server.GlobalState;
26 | import org.apache.lucene.server.IndexState;
27 | import org.apache.lucene.server.params.*;
28 | import net.minidev.json.JSONArray;
29 | import net.minidev.json.JSONObject;
30 | import net.minidev.json.JSONValue;
31 |
32 | /** Handles {@code addDocuments}, by delegating the single
33 | * document to {@link BulkAddDocumentsHandler} */
34 | public class AddDocumentsHandler extends Handler {
35 |
36 | final static StructType TYPE = new StructType(
37 | new Param("indexName", "Index name", new StringType()),
38 | new Param("parent", "The (one) parent document for this block. The value of this key is a single document that @addDocument expects. Be sure to add an indexed field to only the parent document so that you can subsequently provide the filter that identifies only parent documents.",
39 | AddDocumentHandler.DOCUMENT_TYPE),
40 | new Param("children", "List of child documents.",
41 | new ListType(AddDocumentHandler.DOCUMENT_TYPE)));
42 |
43 | @Override
44 | public StructType getType() {
45 | return TYPE;
46 | }
47 |
48 | @Override
49 | public String getTopDoc() {
50 | return "Adds one document block (= single parent and multiple children) to the index. This can be used for block grouping and block joins. Returns the index generation (indexGen) that contains this added document block.";
51 | }
52 |
53 | /** Sole constructor. */
54 | public AddDocumentsHandler(GlobalState state) {
55 | super(state);
56 | }
57 |
58 | @Override
59 | public FinishRequest handle(final IndexState state, final Request r, Map> params) throws Exception {
60 |
61 | state.verifyStarted(r);
62 |
63 | // NOTE: somewhat wasteful since we re-serialize to
64 | // string only to re-parse the JSON, but this allows
65 | // single-source (bulk) for parsing, and apps that care
66 | // about performance will use bulk APIs:
67 |
68 | JSONObject raw = r.getRawParams();
69 | StringBuilder sb = new StringBuilder();
70 | sb.append("{\"indexName\": \"");
71 | sb.append(state.name);
72 | sb.append("\", \"documents\": [");
73 | sb.append(raw.toString());
74 | sb.append("]}");
75 | raw.clear();
76 |
77 | final String bulkRequestString = sb.toString();
78 |
79 | return new FinishRequest() {
80 | @Override
81 | public String finish() throws Exception {
82 | String result = globalState.getHandler("bulkAddDocuments").handleStreamed(new StringReader(bulkRequestString), null);
83 | if (result.indexOf("errors") != -1) {
84 | JSONObject o = (JSONObject) JSONValue.parseStrict(result);
85 | if (o.containsKey("errors")) {
86 | JSONObject err = (JSONObject) ((JSONArray) o.get("errors")).get(0);
87 | throw new IllegalArgumentException((String) err.get("exception"));
88 | }
89 | }
90 | return result;
91 | }
92 | };
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/handlers/AddReplicaHandler.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server.handlers;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.io.InputStream;
21 | import java.io.OutputStream;
22 | import java.net.InetAddress;
23 | import java.net.InetSocketAddress;
24 | import java.util.List;
25 | import java.util.Map;
26 |
27 | import org.apache.lucene.server.FinishRequest;
28 | import org.apache.lucene.server.GlobalState;
29 | import org.apache.lucene.server.IndexState;
30 | import org.apache.lucene.server.ShardState;
31 | import org.apache.lucene.server.params.Request;
32 | import org.apache.lucene.server.params.StructType;
33 | import org.apache.lucene.store.DataInput;
34 | import org.apache.lucene.store.DataOutput;
35 |
36 | /** This is invoked on the primary for an index to record that a new replica is starting */
37 | public class AddReplicaHandler extends Handler {
38 | private static StructType TYPE = new StructType();
39 |
40 | @Override
41 | public StructType getType() {
42 | return TYPE;
43 | }
44 |
45 | @Override
46 | public boolean binaryRequest() {
47 | return true;
48 | }
49 |
50 | @Override
51 | public void handleBinary(InputStream streamIn, DataInput in, DataOutput out, OutputStream streamOut) throws Exception {
52 | String indexName = in.readString();
53 | IndexState indexState = globalState.getIndex(indexName);
54 | ShardState shardState = indexState.getShard(0);
55 | if (shardState.isPrimary() == false) {
56 | throw new IllegalArgumentException("index \"" + indexName + "\" was not started or is not a primary");
57 | }
58 |
59 | int replicaID = in.readVInt();
60 |
61 | System.out.println("AddReplicaHandler: add indexName=" + indexName);
62 |
63 | // nocommit factor this out into readInetSocketAddress:
64 | int port = in.readVInt();
65 | int length = in.readVInt();
66 | byte[] bytes = new byte[length];
67 | in.readBytes(bytes, 0, length);
68 |
69 | InetSocketAddress replicaAddress = new InetSocketAddress(InetAddress.getByAddress(bytes), port);
70 | System.out.println("AddReplicaHandler: now add ID=" + replicaID + " address=" + replicaAddress);
71 | shardState.nrtPrimaryNode.addReplica(replicaID, replicaAddress);
72 | }
73 |
74 | @Override
75 | public FinishRequest handle(IndexState state, Request request, Map> params) {
76 | throw new UnsupportedOperationException();
77 | }
78 |
79 | @Override
80 | public String getTopDoc() {
81 | return "Notifies primary that a new replica is starting";
82 | }
83 |
84 | /** Sole constructor. */
85 | public AddReplicaHandler(GlobalState state) {
86 | super(state);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/handlers/CannedScorer.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server.handlers;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import org.apache.lucene.search.DocIdSetIterator;
21 | import org.apache.lucene.search.Scorer;
22 | import org.apache.lucene.search.Weight;
23 |
24 | // TODO: somehow share w/ the many copies of this class in
25 | // Lucene ... but I don't want to lend the thing any
26 | // credibility!!
27 | final class CannedScorer extends Scorer {
28 |
29 | final float score;
30 | final int doc;
31 |
32 | public CannedScorer(Weight weight, int doc, float score) {
33 | super(weight);
34 | this.doc = doc;
35 | this.score = score;
36 | }
37 |
38 | @Override
39 | public float score() {
40 | return score;
41 | }
42 |
43 | @Override
44 | public DocIdSetIterator iterator() {
45 | return null;
46 | }
47 |
48 | @Override
49 | public int docID() {
50 | return doc;
51 | }
52 |
53 | @Override
54 | public float getMaxScore(int upTo) {
55 | return 1f;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/handlers/CommitHandler.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server.handlers;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.io.IOException;
21 | import java.util.List;
22 | import java.util.Map;
23 |
24 | import org.apache.lucene.server.FinishRequest;
25 | import org.apache.lucene.server.GlobalState;
26 | import org.apache.lucene.server.IndexState;
27 | import org.apache.lucene.server.ShardState;
28 | import org.apache.lucene.server.params.*;
29 |
30 | /** Handles {@code commit}. */
31 | public class CommitHandler extends Handler {
32 |
33 | private static StructType TYPE = new StructType(
34 | new Param("indexName", "Index name", new StringType()));
35 |
36 | /** Sole constructor. */
37 | public CommitHandler(GlobalState state) {
38 | super(state);
39 | }
40 |
41 | @Override
42 | public StructType getType() {
43 | return TYPE;
44 | }
45 |
46 | @Override
47 | public String getTopDoc() {
48 | return "Commits all pending changes to durable storage.";
49 | }
50 |
51 | @Override
52 | public FinishRequest handle(final IndexState indexState, Request r, Map> params) throws Exception {
53 | final ShardState shardState = indexState.getShard(0);
54 | return new FinishRequest() {
55 | @Override
56 | public String finish() throws IOException {
57 | long gen = indexState.commit();
58 | return "{\"indexGen\": " + gen + "}";
59 | }
60 | };
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/handlers/CreateIndexHandler.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server.handlers;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.nio.file.Path;
21 | import java.nio.file.Paths;
22 | import java.util.List;
23 | import java.util.Map;
24 |
25 | import org.apache.lucene.server.FinishRequest;
26 | import org.apache.lucene.server.GlobalState;
27 | import org.apache.lucene.server.IndexState;
28 | import org.apache.lucene.server.params.Param;
29 | import org.apache.lucene.server.params.Request;
30 | import org.apache.lucene.server.params.StringType;
31 | import org.apache.lucene.server.params.StructType;
32 |
33 | /** Handles {@code createIndex}. */
34 | public class CreateIndexHandler extends Handler {
35 | private static StructType TYPE = new StructType(
36 | new Param("indexName", "Index name", new StringType()),
37 | new Param("rootDir", "Filesystem path where all state is stored", new StringType()));
38 |
39 | /** Sole constructor. */
40 | public CreateIndexHandler(GlobalState state) {
41 | super(state);
42 | requiresIndexName = false;
43 | }
44 |
45 | @Override
46 | public StructType getType() {
47 | return TYPE;
48 | }
49 |
50 | @Override
51 | public String getTopDoc() {
52 | return "Create an index";
53 | }
54 |
55 | @Override
56 | public FinishRequest handle(final IndexState indexState, final Request r, Map> params) throws Exception {
57 | final String indexName = r.getString("indexName");
58 | if (!IndexState.isSimpleName(indexName)) {
59 | r.fail("indexName", "invalid indexName \"" + indexName + "\": must be [a-zA-Z_][a-zA-Z0-9]*");
60 | }
61 | final Path rootDir;
62 | if (r.hasParam("rootDir")) {
63 | rootDir = Paths.get(r.getString("rootDir"));
64 | } else {
65 | rootDir = null;
66 | }
67 |
68 | return new FinishRequest() {
69 | @Override
70 | public String finish() throws Exception {
71 | IndexState indexState;
72 | try {
73 | indexState = globalState.createIndex(indexName, rootDir);
74 | } catch (IllegalArgumentException iae) {
75 | throw r.bad("invalid indexName \"" + indexName + "\": " + iae.toString(), iae);
76 | }
77 | // Create the first shard
78 | indexState.addShard(0, true);
79 | return "{}";
80 | }
81 | };
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/handlers/DeleteAllDocumentsHandler.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server.handlers;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.io.IOException;
21 | import java.util.List;
22 | import java.util.Map;
23 |
24 | import org.apache.lucene.server.FinishRequest;
25 | import org.apache.lucene.server.GlobalState;
26 | import org.apache.lucene.server.IndexState;
27 | import org.apache.lucene.server.ShardState;
28 | import org.apache.lucene.server.params.*;
29 | import net.minidev.json.JSONObject;
30 |
31 | /** Handles {@code deleteAllDocuments}. */
32 | public class DeleteAllDocumentsHandler extends Handler {
33 |
34 | private final static StructType TYPE =
35 | new StructType(new Param("indexName", "Which index to search", new StringType()));
36 |
37 | @Override
38 | public StructType getType() {
39 | return TYPE;
40 | }
41 |
42 | @Override
43 | public String getTopDoc() {
44 | return "Removes all documents in the index, but keeps all registered fields, settings and any built suggesters.";
45 | }
46 |
47 | /** Sole constructor. */
48 | public DeleteAllDocumentsHandler(GlobalState state) {
49 | super(state);
50 | }
51 |
52 | @Override
53 | public FinishRequest handle(final IndexState indexState, Request r, Map> params) throws Exception {
54 | indexState.verifyStarted(r);
55 | ShardState shardState = indexState.getShard(0);
56 | return new FinishRequest() {
57 | @Override
58 | public String finish() throws IOException {
59 | // nocommit should also somehow reset taxo index?
60 | long gen = shardState.writer.deleteAll();
61 | JSONObject r = new JSONObject();
62 | r.put("indexGen", gen);
63 | return r.toString();
64 | }
65 | };
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/java/org/apache/lucene/server/handlers/DeleteDocumentsHandler.java:
--------------------------------------------------------------------------------
1 | package org.apache.lucene.server.handlers;
2 |
3 | /*
4 | * Licensed to the Apache Software Foundation (ASF) under one or more
5 | * contributor license agreements. See the NOTICE file distributed with
6 | * this work for additional information regarding copyright ownership.
7 | * The ASF licenses this file to You under the Apache License, Version 2.0
8 | * (the "License"); you may not use this file except in compliance with
9 | * the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | */
19 |
20 | import java.io.IOException;
21 | import java.util.List;
22 | import java.util.Map;
23 |
24 | import org.apache.lucene.index.Term;
25 | import org.apache.lucene.server.FinishRequest;
26 | import org.apache.lucene.server.GlobalState;
27 | import org.apache.lucene.server.IndexState;
28 | import org.apache.lucene.server.ShardState;
29 | import org.apache.lucene.server.params.ListType;
30 | import org.apache.lucene.server.params.Param;
31 | import org.apache.lucene.server.params.Request;
32 | import org.apache.lucene.server.params.StringType;
33 | import org.apache.lucene.server.params.StructType;
34 |
35 | import net.minidev.json.JSONObject;
36 |
37 | /** Handles {@code deleteDocuments}. */
38 | public class DeleteDocumentsHandler extends Handler {
39 | // TODO: support delete by query too:
40 | // TODO: support bulk api?
41 | final static StructType TYPE = new StructType(
42 | new Param("indexName", "Index name", new StringType()),
43 | new Param("field", "Field to match to identify the deleted documents.", new StringType()),
44 | new Param("values", "Values to delete.", new ListType(new StringType())));
45 |
46 | @Override
47 | public StructType getType() {
48 | return TYPE;
49 | }
50 |
51 | @Override
52 | public String getTopDoc() {
53 | return "Delete documents. Returns the index generation (indexGen) that reflext the deletion.";
54 | }
55 |
56 | /** Sole constructor. */
57 | public DeleteDocumentsHandler(GlobalState state) {
58 | super(state);
59 | }
60 |
61 | @Override
62 | public FinishRequest handle(final IndexState indexState, final Request r, Map> params) throws Exception {
63 | final ShardState shardState = indexState.getShard(0);
64 | final String field = r.getString("field");
65 | final List