001/*
002 * Copyright (c) 2007-2022 The Cascading Authors. All Rights Reserved.
003 *
004 * Project and contact information: https://cascading.wensel.net/
005 *
006 * This file is part of the Cascading project.
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *     http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020
021package cascading.local.tap.splunk;
022
023import java.io.InputStream;
024import java.io.OutputStream;
025import java.net.URI;
026import java.net.URISyntaxException;
027import java.util.Map;
028import java.util.Properties;
029
030import cascading.flow.FlowProcess;
031import cascading.scheme.Scheme;
032import cascading.tap.SinkMode;
033import cascading.tap.Tap;
034import cascading.tap.TapException;
035import cascading.tuple.TupleEntryIterator;
036import cascading.tuple.TupleEntrySchemeIterator;
037import com.splunk.JobExportArgs;
038import com.splunk.Service;
039import com.splunk.ServiceArgs;
040
041/**
042 *
043 */
044public abstract class SplunkTap extends Tap<Properties, InputStream, OutputStream>
045  {
046  private ServiceArgs serviceArgs;
047  private Service service;
048  private JobExportArgs exportArgs;
049
050  public SplunkTap( SplunkScheme scheme, String host, int port )
051    {
052    super( (Scheme<Properties, InputStream, OutputStream, ?, ?>) scheme, SinkMode.UPDATE );
053
054    ServiceArgs serviceArgs = new ServiceArgs();
055
056    serviceArgs.setHost( host );
057    serviceArgs.setPort( port );
058
059    this.serviceArgs = serviceArgs;
060    }
061
062  public SplunkTap( SplunkScheme scheme )
063    {
064    super( (Scheme<Properties, InputStream, OutputStream, ?, ?>) scheme, SinkMode.UPDATE );
065    }
066
067  public SplunkTap( SplunkScheme scheme, SinkMode sinkMode )
068    {
069    super( (Scheme<Properties, InputStream, OutputStream, ?, ?>) scheme, sinkMode );
070    }
071
072  public SplunkTap( SplunkScheme scheme, ServiceArgs serviceArgs, SinkMode sinkMode )
073    {
074    super( (Scheme<Properties, InputStream, OutputStream, ?, ?>) scheme, sinkMode );
075    this.serviceArgs = serviceArgs;
076    }
077
078  public SplunkTap( SplunkScheme scheme, ServiceArgs serviceArgs )
079    {
080    super( (Scheme<Properties, InputStream, OutputStream, ?, ?>) scheme, SinkMode.UPDATE );
081    this.serviceArgs = serviceArgs;
082    }
083
084  public SplunkTap( SplunkScheme scheme, ServiceArgs serviceArgs, JobExportArgs exportArgs, SinkMode sinkMode )
085    {
086    super( (Scheme<Properties, InputStream, OutputStream, ?, ?>) scheme, sinkMode );
087    this.serviceArgs = serviceArgs;
088    this.exportArgs = exportArgs;
089    }
090
091  public SplunkTap( SplunkScheme scheme, ServiceArgs serviceArgs, JobExportArgs exportArgs )
092    {
093    super( (Scheme<Properties, InputStream, OutputStream, ?, ?>) scheme, SinkMode.UPDATE );
094    this.serviceArgs = serviceArgs;
095    this.exportArgs = exportArgs;
096    }
097
098  public SplunkTap( SplunkScheme scheme, Service service, JobExportArgs exportArgs, SinkMode sinkMode )
099    {
100    super( (Scheme<Properties, InputStream, OutputStream, ?, ?>) scheme, sinkMode );
101    this.service = service;
102    this.exportArgs = exportArgs;
103    }
104
105  public SplunkTap( SplunkScheme scheme, Service service, JobExportArgs exportArgs )
106    {
107    super( (Scheme<Properties, InputStream, OutputStream, ?, ?>) scheme, SinkMode.UPDATE );
108    this.service = service;
109    this.exportArgs = exportArgs;
110    }
111
112  protected Service getService()
113    {
114    if( service != null )
115      return service;
116
117    service = Service.connect( serviceArgs );
118
119    return service;
120    }
121
122  @Override
123  public String getIdentifier()
124    {
125    URI splunk;
126
127    try
128      {
129      splunk = new URI( getService().getScheme().equals( "https" ) ? "splunks" : "splunk", null, getService().getHost(), getService().getPort(), getSplunkPath(), getSplunkQuery(), null );
130      }
131    catch( URISyntaxException exception )
132      {
133      throw new TapException( "could not create identifier", exception );
134      }
135
136    return splunk.toString();
137    }
138
139  protected abstract String getSplunkQuery();
140
141  protected abstract String getSplunkPath();
142
143  @Override
144  public TupleEntryIterator openForRead( FlowProcess<? extends Properties> flowProcess, InputStream inputStream )
145    {
146    Properties properties = new Properties();
147
148    sourceConfInit( flowProcess, properties );
149
150    JobExportArgs exportArgs = new JobExportArgs();
151
152    if( this.exportArgs != null )
153      exportArgs.putAll( this.exportArgs );
154
155    // grab the provided args object and add
156    if( properties.get( "args" ) != null )
157      exportArgs.putAll( (Map<? extends String, ?>) properties.get( "args" ) );
158
159    if( !exportArgs.containsKey( "timeout" ) )
160      exportArgs.setTimeout( 60 );
161
162    String search = getSearch();
163
164    inputStream = getService().export( search, exportArgs );
165
166    return new TupleEntrySchemeIterator<Properties, InputStream>( flowProcess, this, getScheme(), inputStream, this::getIdentifier );
167    }
168
169  protected abstract String getSearch();
170  }