11package com .marklogic .hub .web .controller .api ;
22
3+ import java .io .ByteArrayInputStream ;
34import java .io .IOException ;
5+ import java .io .InputStream ;
46import java .math .BigInteger ;
7+ import java .nio .charset .StandardCharsets ;
58import java .util .ArrayList ;
69import java .util .List ;
710
1619import org .springframework .batch .core .JobExecution ;
1720import org .springframework .batch .core .JobExecutionListener ;
1821import org .springframework .beans .factory .annotation .Autowired ;
22+ import org .springframework .core .io .InputStreamResource ;
23+ import org .springframework .http .HttpHeaders ;
1924import org .springframework .http .MediaType ;
25+ import org .springframework .http .ResponseEntity ;
26+ import org .springframework .util .StringUtils ;
2027import org .springframework .validation .BindingResult ;
2128import org .springframework .web .bind .annotation .RequestBody ;
2229import org .springframework .web .bind .annotation .RequestMapping ;
2532import org .springframework .web .bind .annotation .RestController ;
2633
2734import com .marklogic .hub .Mlcp ;
35+ import com .marklogic .hub .Mlcp .MlcpSource ;
2836import com .marklogic .hub .Mlcp .SourceOptions ;
2937import com .marklogic .hub .config .EnvironmentConfiguration ;
3038import com .marklogic .hub .flow .Flow ;
3139import com .marklogic .hub .flow .FlowType ;
3240import com .marklogic .hub .model .EntityModel ;
3341import com .marklogic .hub .model .FlowModel ;
34- import com .marklogic .hub .model .RunFlowModel ;
42+ import com .marklogic .hub .model .FlowOptionsModel ;
3543import com .marklogic .hub .service .CancellableTask ;
3644import com .marklogic .hub .service .FlowManagerService ;
3745import com .marklogic .hub .service .TaskManagerService ;
@@ -45,6 +53,10 @@ public class FlowApiController extends BaseController {
4553
4654 private static final Logger LOGGER = LoggerFactory
4755 .getLogger (FlowApiController .class );
56+
57+ private static final String MLCP_OPTIONS_FILENAME = "mlcpOptions.txt" ;
58+
59+ private static final String NEW_LINE = "\n " ;
4860
4961 @ Autowired
5062 private EnvironmentConfiguration environmentConfiguration ;
@@ -137,7 +149,7 @@ public void run(BasicFuture<?> resultFuture) {
137149 }
138150
139151 @ RequestMapping (value = "/run" , method = RequestMethod .POST )
140- public BigInteger runFlow (@ RequestBody RunFlowModel runFlow ) {
152+ public BigInteger runFlow (@ RequestBody FlowOptionsModel runFlow ) {
141153 CancellableTask task = new CancellableTask () {
142154
143155 private JobExecution jobExecution ;
@@ -190,9 +202,9 @@ public void afterJob(JobExecution jobExecution) {
190202 }
191203
192204 @ RequestMapping (value ="/run/input" , method = RequestMethod .POST )
193- public BigInteger runInputFlow (@ RequestBody RunFlowModel runFlow ) {
205+ public BigInteger runInputFlow (@ RequestBody FlowOptionsModel flowOptionsModel ) {
194206
195- saveInputPath (runFlow );
207+ saveInputPath (flowOptionsModel );
196208
197209 CancellableTask task = new CancellableTask () {
198210
@@ -204,31 +216,16 @@ public void cancel(BasicFuture<?> resultFuture) {
204216 @ Override
205217 public void run (BasicFuture <?> resultFuture ) {
206218 try {
207- Flow flow = flowManagerService .getFlow (runFlow .getEntityName (), runFlow .getFlowName ());
208-
209- Mlcp mlcp = new Mlcp (
210- environmentConfiguration .getMLHost ()
211- ,Integer .parseInt (environmentConfiguration .getMLStagingRestPort ())
212- ,environmentConfiguration .getMLUsername ()
213- ,environmentConfiguration .getMLPassword ()
214- );
215-
216- SourceOptions sourceOptions = new SourceOptions (
217- runFlow .getEntityName (), runFlow .getFlowName (),
218- FlowType .INPUT .toString (),
219- flow .getDataFormat ());
220-
221- sourceOptions .setInputFileType (runFlow .getInputFileType ());
222- sourceOptions .setOtherOptions (runFlow .getOtherOptions ());
223- mlcp .addSourceDirectory (runFlow .getInputPath (), sourceOptions );
219+ SourceOptions sourceOptions = createSourceOptionsInstance (flowOptionsModel );
220+ Mlcp mlcp = createMlcpInstance (flowOptionsModel ,sourceOptions );
224221 mlcp .loadContent ();
225222
226223 resultFuture .completed (null );
227224 }
228225
229226 catch (IOException | JSONException e ) {
230227 LOGGER .error ("Error encountered while trying to run flow: "
231- + runFlow .getEntityName () + " > " + runFlow .getFlowName (),
228+ + flowOptionsModel .getEntityName () + " > " + flowOptionsModel .getFlowName (),
232229 e );
233230 resultFuture .failed (e );
234231 }
@@ -238,6 +235,31 @@ public void run(BasicFuture<?> resultFuture) {
238235 return taskManagerService .addTask (task );
239236 }
240237
238+ protected Mlcp createMlcpInstance (FlowOptionsModel flowOptionsModel , SourceOptions sourceOptions ) throws NumberFormatException , IOException {
239+ Mlcp mlcp = new Mlcp (
240+ environmentConfiguration .getMLHost ()
241+ ,Integer .parseInt (environmentConfiguration .getMLStagingRestPort ())
242+ ,environmentConfiguration .getMLUsername ()
243+ ,environmentConfiguration .getMLPassword ()
244+ );
245+ mlcp .addSourceDirectory (flowOptionsModel .getInputPath (), sourceOptions );
246+ return mlcp ;
247+ }
248+
249+ protected SourceOptions createSourceOptionsInstance (FlowOptionsModel flowOptionsModel ) throws NumberFormatException , IOException {
250+ Flow flow = flowManagerService .getFlow (flowOptionsModel .getEntityName (), flowOptionsModel .getFlowName ());
251+
252+ SourceOptions sourceOptions = new SourceOptions (
253+ flowOptionsModel .getEntityName (), flowOptionsModel .getFlowName (),
254+ FlowType .INPUT .toString (),
255+ flow .getDataFormat ());
256+
257+ sourceOptions .setInputFileType (flowOptionsModel .getInputFileType ());
258+ sourceOptions .setOtherOptions (flowOptionsModel .getOtherOptions ());
259+
260+ return sourceOptions ;
261+ }
262+
241263 @ RequestMapping (value = "/input-path" , method = RequestMethod .GET , produces = { MediaType .TEXT_PLAIN_VALUE })
242264 @ ResponseBody
243265 public String getPreviousInputPath (HttpServletRequest request ) {
@@ -251,7 +273,7 @@ private String getPreviousInputPath(String entityName, String flowName) {
251273 return value == null ? "." : value ;
252274 }
253275
254- private void saveInputPath (RunFlowModel runFlow ) {
276+ private void saveInputPath (FlowOptionsModel runFlow ) {
255277 environmentConfiguration .saveOrUpdateFlowInputPath (runFlow .getEntityName (), runFlow .getFlowName (), runFlow .getInputPath ());
256278 }
257279
@@ -267,5 +289,33 @@ public void runFlowsInParallel(HttpServletRequest request) {
267289 flowManagerService .runFlowsInParallel (flows .toArray (new Flow [flows
268290 .size ()]));
269291 }
292+
293+ @ RequestMapping (value = "/options/download" , method = RequestMethod .POST , consumes = { MediaType .APPLICATION_JSON_UTF8_VALUE }, produces = { MediaType .TEXT_PLAIN_VALUE })
294+ public ResponseEntity <InputStreamResource > downloadMlcpConfig (@ RequestBody FlowOptionsModel flowOptionsModel ) throws IOException , NumberFormatException , JSONException {
295+ String mlcpConfigContent = buildMlcpConfigContent (flowOptionsModel );
296+ byte [] contentBytes = mlcpConfigContent .getBytes (StandardCharsets .UTF_8 );
297+ InputStream inputStream = new ByteArrayInputStream (contentBytes );
298+ HttpHeaders headers = new HttpHeaders ();
299+ addRemoveCachingInHeaders (headers );
300+ headers .add ("content-disposition" , "attachment; filename=" + MLCP_OPTIONS_FILENAME );
301+ return ResponseEntity
302+ .ok ()
303+ .contentLength (contentBytes .length )
304+ .contentType (MediaType .TEXT_PLAIN )
305+ .headers (headers )
306+ .body (new InputStreamResource (inputStream ));
307+ }
270308
309+ private String buildMlcpConfigContent (FlowOptionsModel flowOptionsModel ) throws NumberFormatException , IOException , JSONException {
310+ SourceOptions sourceOptions = createSourceOptionsInstance (flowOptionsModel );
311+ Mlcp mlcp = createMlcpInstance (flowOptionsModel ,sourceOptions );
312+ List <String > mlcpOptions = mlcp .getMlcpOptions (new MlcpSource (flowOptionsModel .getInputPath (), sourceOptions ));
313+ return StringUtils .collectionToDelimitedString (mlcpOptions , NEW_LINE );
314+ }
315+
316+ private void addRemoveCachingInHeaders (HttpHeaders headers ) {
317+ headers .add ("Cache-Control" , "no-cache, no-store, must-revalidate" );
318+ headers .add ("Pragma" , "no-cache" );
319+ headers .add ("Expires" , "0" );
320+ }
271321}
0 commit comments