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.BufferedOutputStream;
024import java.io.IOException;
025import java.io.OutputStream;
026import java.net.Socket;
027import java.util.Properties;
028
029import cascading.flow.FlowProcess;
030import cascading.tap.SinkMode;
031import cascading.tuple.TupleEntryCollector;
032import cascading.tuple.TupleEntrySchemeCollector;
033import com.splunk.Index;
034import com.splunk.JobExportArgs;
035import com.splunk.Service;
036import com.splunk.ServiceArgs;
037
038/**
039 * Class SplunkIndexTap can return all the results from a given index or write to the index.
040 * <p>
041 * It is currently assumed the index name given is not a pattern/wildcard.
042 * <p>
043 * In order to source (only) from a search result, see {@link SplunkSearchTap}.
044 */
045public class SplunkIndexTap extends SplunkTap
046  {
047  private String indexName;
048
049  public SplunkIndexTap( SplunkScheme scheme, String host, int port, String indexName )
050    {
051    super( scheme, host, port );
052    this.indexName = indexName;
053    }
054
055  public SplunkIndexTap( SplunkScheme scheme, ServiceArgs serviceArgs, String indexName )
056    {
057    super( scheme, serviceArgs );
058    this.indexName = indexName;
059    }
060
061  public SplunkIndexTap( SplunkScheme scheme, ServiceArgs serviceArgs, JobExportArgs exportArgs, String indexName )
062    {
063    super( scheme, serviceArgs, exportArgs );
064    this.indexName = indexName;
065    }
066
067  public SplunkIndexTap( SplunkScheme scheme, ServiceArgs serviceArgs, JobExportArgs exportArgs, SinkMode sinkMode, String indexName )
068    {
069    super( scheme, serviceArgs, exportArgs, sinkMode );
070    this.indexName = indexName;
071    }
072
073  public SplunkIndexTap( SplunkScheme scheme, Service service, String indexName )
074    {
075    super( scheme, service, null );
076    this.indexName = indexName;
077    }
078
079  public SplunkIndexTap( SplunkScheme scheme, Service service, JobExportArgs exportArgs, String indexName )
080    {
081    super( scheme, service, exportArgs );
082    this.indexName = indexName;
083    }
084
085  public SplunkIndexTap( SplunkScheme scheme, Service service, JobExportArgs exportArgs, SinkMode sinkMode, String indexName )
086    {
087    super( scheme, service, exportArgs, sinkMode );
088    this.indexName = indexName;
089    }
090
091  @Override
092  protected String getSplunkQuery()
093    {
094    return null;
095    }
096
097  @Override
098  protected String getSplunkPath()
099    {
100    return "/" + indexName;
101    }
102
103  @Override
104  protected String getSearch()
105    {
106    return String.format( "search index=%s *", indexName );
107    }
108
109  @Override
110  public TupleEntryCollector openForWrite( FlowProcess<? extends Properties> flowProcess, OutputStream outputStream ) throws IOException
111    {
112    Index index = getOrCreateIndex();
113    Socket socket = index.attach();
114
115    OutputStream stream = new BufferedOutputStream( socket.getOutputStream() )
116      {
117      @Override
118      public void close() throws IOException
119        {
120        super.close();
121
122        socket.close();
123        }
124      };
125
126    return new TupleEntrySchemeCollector<Properties, OutputStream>( flowProcess, this, getScheme(), stream, this::getIdentifier );
127    }
128
129  protected Index getOrCreateIndex()
130    {
131    Index index = getIndex();
132
133    if( index == null )
134      index = getService().getIndexes().create( indexName );
135
136    return index;
137    }
138
139  protected Index getIndex()
140    {
141    return getService().getIndexes().get( indexName );
142    }
143
144  @Override
145  public boolean createResource( Properties conf )
146    {
147    Index index = getOrCreateIndex();
148
149    return index != null;
150    }
151
152  @Override
153  public boolean deleteResource( Properties conf )
154    {
155    Index index = getIndex();
156
157    index.remove();
158
159    return true;
160    }
161
162  @Override
163  public boolean resourceExists( Properties conf ) throws IOException
164    {
165    return getIndex() != null;
166    }
167
168  @Override
169  public long getModifiedTime( Properties conf ) throws IOException
170    {
171    return resourceExists( conf ) ? Long.MAX_VALUE : 0;
172    }
173  }