New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create a simpler Getting Started with demo data #1408
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
1c5434c
add demo source & demo dest
michel-tricot a3931c8
progress
michel-tricot 9190694
lint
michel-tricot 38620ed
GitBook: [mt-demo-data] 4 pages modified
michel-tricot 37446a1
GitBook: [mt-demo-data] 3 pages modified
michel-tricot 5ed1850
Merge branch 'master' into mt-demo-data
michel-tricot aa648cf
Merge branch 'mt-demo-data' of github.com:airbytehq/airbyte into mt-d…
michel-tricot 5f0fd23
GitBook: [mt-demo-data] 2 pages modified
michel-tricot 51652b3
GitBook: [mt-demo-data] one page modified
michel-tricot 27bd2b1
GitBook: [mt-demo-data] 2 pages modified
michel-tricot 360b93e
remove demo
michel-tricot 748a478
Merge branch 'mt-demo-data' of github.com:airbytehq/airbyte into mt-d…
michel-tricot b32f1e9
GitBook: [mt-demo-data] 5 pages and 4 assets modified
michel-tricot ae89e2c
Merge branch 'mt-demo-data' of github.com:airbytehq/airbyte into mt-d…
michel-tricot fbca103
update readme
michel-tricot de379bf
update link
michel-tricot 86d7380
Merge branch 'master' into mt-demo-data
michel-tricot a957cc6
GitBook: [mt-demo-data] one page modified
68b8fe9
lint
michel-tricot de63587
Update local-csv.md
ChristopheDuong 40a5e41
Update local-json.md
ChristopheDuong e1d1cdf
GitBook: [mt-demo-data] 83 pages modified
michel-tricot e69352a
fix gitbook rewrite
michel-tricot File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
...esources/config/STANDARD_DESTINATION_DEFINITION/a625d593-bba5-4a1c-a53d-2d246268a816.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"destinationDefinitionId": "a625d593-bba5-4a1c-a53d-2d246268a816", | ||
"name": "Local JSON", | ||
"dockerRepository": "airbyte/destination-local-json", | ||
"dockerImageTag": "0.1.0", | ||
"documentationUrl": "https://docs.airbyte.io/integrations/destinations/local-json" | ||
} |
2 changes: 1 addition & 1 deletion
2
...ain/resources/config/STANDARD_SOURCE_DEFINITION/9fed261d-d107-47fd-8c8b-323023db6e20.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 8 additions & 3 deletions
11
airbyte-config/init/src/main/resources/seed/destination_definitions.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
airbyte-config/init/src/main/resources/seed/source_definitions.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
airbyte-integrations/connectors/destination-local-json/.dockerignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
* | ||
!Dockerfile | ||
!build |
11 changes: 11 additions & 0 deletions
11
airbyte-integrations/connectors/destination-local-json/Dockerfile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
FROM airbyte/integration-base-java:dev | ||
|
||
WORKDIR /airbyte | ||
ENV APPLICATION destination-local-json | ||
|
||
COPY build/distributions/${APPLICATION}*.tar ${APPLICATION}.tar | ||
|
||
RUN tar xf ${APPLICATION}.tar --strip-components=1 | ||
|
||
LABEL io.airbyte.version=0.1.0 | ||
LABEL io.airbyte.name=airbyte/destination-local-json |
18 changes: 18 additions & 0 deletions
18
airbyte-integrations/connectors/destination-local-json/build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
plugins { | ||
id 'application' | ||
id 'airbyte-docker' | ||
id 'airbyte-integration-test-java' | ||
} | ||
|
||
application { | ||
mainClass = 'io.airbyte.integrations.destination.local_json.LocalJsonDestination' | ||
} | ||
|
||
dependencies { | ||
implementation project(':airbyte-config:models') | ||
implementation project(':airbyte-protocol:models') | ||
implementation project(':airbyte-integrations:bases:base-java') | ||
implementation files(project(':airbyte-integrations:bases:base-java').airbyteDocker.outputs) | ||
|
||
integrationTestJavaImplementation project(':airbyte-integrations:bases:standard-destination-test') | ||
} |
234 changes: 234 additions & 0 deletions
234
...on/src/main/java/io/airbyte/integrations/destination/local_json/LocalJsonDestination.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
/* | ||
* MIT License | ||
* | ||
* Copyright (c) 2020 Airbyte | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in all | ||
* copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
* SOFTWARE. | ||
*/ | ||
|
||
package io.airbyte.integrations.destination.local_json; | ||
|
||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.google.common.collect.ImmutableMap; | ||
import io.airbyte.commons.json.Jsons; | ||
import io.airbyte.commons.resources.MoreResources; | ||
import io.airbyte.integrations.base.Destination; | ||
import io.airbyte.integrations.base.DestinationConsumer; | ||
import io.airbyte.integrations.base.FailureTrackingConsumer; | ||
import io.airbyte.integrations.base.IntegrationRunner; | ||
import io.airbyte.integrations.base.SQLNamingResolvable; | ||
import io.airbyte.integrations.base.StandardSQLNaming; | ||
import io.airbyte.protocol.models.AirbyteConnectionStatus; | ||
import io.airbyte.protocol.models.AirbyteConnectionStatus.Status; | ||
import io.airbyte.protocol.models.AirbyteMessage; | ||
import io.airbyte.protocol.models.ConfiguredAirbyteCatalog; | ||
import io.airbyte.protocol.models.ConfiguredAirbyteStream; | ||
import io.airbyte.protocol.models.ConnectorSpecification; | ||
import io.airbyte.protocol.models.SyncMode; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.io.Writer; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.nio.file.StandardCopyOption; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.UUID; | ||
import org.apache.commons.io.FileUtils; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class LocalJsonDestination implements Destination { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(LocalJsonDestination.class); | ||
|
||
static final String FIELD_DATA = "data"; | ||
static final String FIELD_AB_ID = "ab_id"; | ||
static final String FIELD_EMITTED_AT = "emitted_at"; | ||
|
||
static final String DESTINATION_PATH_FIELD = "destination_path"; | ||
|
||
private final SQLNamingResolvable namingResolver; | ||
|
||
public LocalJsonDestination() { | ||
namingResolver = new StandardSQLNaming(); | ||
} | ||
|
||
@Override | ||
public ConnectorSpecification spec() throws IOException { | ||
final String resourceString = MoreResources.readResource("spec.json"); | ||
return Jsons.deserialize(resourceString, ConnectorSpecification.class); | ||
} | ||
|
||
@Override | ||
public AirbyteConnectionStatus check(JsonNode config) { | ||
try { | ||
FileUtils.forceMkdir(getDestinationPath(config).toFile()); | ||
} catch (Exception e) { | ||
return new AirbyteConnectionStatus().withStatus(Status.FAILED).withMessage(e.getMessage()); | ||
} | ||
return new AirbyteConnectionStatus().withStatus(Status.SUCCEEDED); | ||
} | ||
|
||
@Override | ||
public SQLNamingResolvable getNamingResolver() { | ||
return namingResolver; | ||
} | ||
|
||
/** | ||
* @param config - destination config. | ||
* @param catalog - schema of the incoming messages. | ||
* @return - a consumer to handle writing records to the filesystem. | ||
* @throws IOException - exception throw in manipulating the filesystem. | ||
*/ | ||
@Override | ||
public DestinationConsumer<AirbyteMessage> write(JsonNode config, ConfiguredAirbyteCatalog catalog) throws IOException { | ||
final Path destinationDir = getDestinationPath(config); | ||
|
||
FileUtils.forceMkdir(destinationDir.toFile()); | ||
|
||
final Map<String, WriteConfig> writeConfigs = new HashMap<>(); | ||
for (final ConfiguredAirbyteStream stream : catalog.getStreams()) { | ||
final String streamName = stream.getStream().getName(); | ||
final Path finalPath = destinationDir.resolve(getNamingResolver().getRawTableName(streamName) + ".jsonl"); | ||
final Path tmpPath = destinationDir.resolve(getNamingResolver().getTmpTableName(streamName) + ".jsonl"); | ||
|
||
final boolean isIncremental = stream.getSyncMode() == SyncMode.INCREMENTAL; | ||
if (isIncremental && finalPath.toFile().exists()) { | ||
Files.copy(finalPath, tmpPath, StandardCopyOption.REPLACE_EXISTING); | ||
} | ||
|
||
final Writer writer = new FileWriter(tmpPath.toFile(), isIncremental); | ||
writeConfigs.put(stream.getStream().getName(), new WriteConfig(writer, tmpPath, finalPath)); | ||
} | ||
|
||
return new JsonConsumer(writeConfigs, catalog); | ||
} | ||
|
||
/** | ||
* Extract provided path. | ||
* | ||
* @param config - config object | ||
* @return absolute path where to write files. | ||
*/ | ||
private Path getDestinationPath(JsonNode config) { | ||
Path destinationPath = Paths.get(config.get(DESTINATION_PATH_FIELD).asText()); | ||
|
||
if (!destinationPath.startsWith("/local")) | ||
destinationPath = Path.of("/local").resolve(destinationPath); | ||
|
||
return destinationPath; | ||
} | ||
|
||
/** | ||
* This consumer writes individual records to temporary files. If all of the messages are written | ||
* successfully, it moves the tmp files to files named by their respective stream. If there are any | ||
* failures, nothing is written. | ||
*/ | ||
private static class JsonConsumer extends FailureTrackingConsumer<AirbyteMessage> { | ||
|
||
private final Map<String, WriteConfig> writeConfigs; | ||
private final ConfiguredAirbyteCatalog catalog; | ||
|
||
public JsonConsumer(Map<String, WriteConfig> writeConfigs, ConfiguredAirbyteCatalog catalog) { | ||
LOGGER.info("initializing consumer."); | ||
this.catalog = catalog; | ||
this.writeConfigs = writeConfigs; | ||
} | ||
|
||
@Override | ||
protected void acceptTracked(AirbyteMessage message) throws Exception { | ||
|
||
// ignore other message types. | ||
if (message.getType() == AirbyteMessage.Type.RECORD) { | ||
if (!writeConfigs.containsKey(message.getRecord().getStream())) { | ||
throw new IllegalArgumentException( | ||
String.format("Message contained record from a stream that was not in the catalog. \ncatalog: %s , \nmessage: %s", | ||
Jsons.serialize(catalog), Jsons.serialize(message))); | ||
} | ||
|
||
final Writer writer = writeConfigs.get(message.getRecord().getStream()).getWriter(); | ||
writer.write(Jsons.serialize(ImmutableMap.of( | ||
FIELD_AB_ID, UUID.randomUUID(), | ||
FIELD_EMITTED_AT, message.getRecord().getEmittedAt(), | ||
FIELD_DATA, message.getRecord().getData()))); | ||
writer.write(System.lineSeparator()); | ||
} | ||
} | ||
|
||
@Override | ||
protected void close(boolean hasFailed) throws IOException { | ||
LOGGER.info("finalizing consumer."); | ||
|
||
for (final Map.Entry<String, WriteConfig> entries : writeConfigs.entrySet()) { | ||
try { | ||
entries.getValue().getWriter().flush(); | ||
entries.getValue().getWriter().close(); | ||
} catch (Exception e) { | ||
hasFailed = true; | ||
LOGGER.error("failed to close writer for: {}.", entries.getKey()); | ||
} | ||
} | ||
// do not persist the data, if there are any failures. | ||
if (!hasFailed) { | ||
for (final WriteConfig writeConfig : writeConfigs.values()) { | ||
Files.move(writeConfig.getTmpPath(), writeConfig.getFinalPath(), StandardCopyOption.REPLACE_EXISTING); | ||
} | ||
} | ||
// clean up tmp files. | ||
for (final WriteConfig writeConfig : writeConfigs.values()) { | ||
Files.deleteIfExists(writeConfig.getTmpPath()); | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
private static class WriteConfig { | ||
|
||
private final Writer writer; | ||
private final Path tmpPath; | ||
private final Path finalPath; | ||
|
||
public WriteConfig(Writer writer, Path tmpPath, Path finalPath) { | ||
this.writer = writer; | ||
this.tmpPath = tmpPath; | ||
this.finalPath = finalPath; | ||
} | ||
|
||
public Writer getWriter() { | ||
return writer; | ||
} | ||
|
||
public Path getTmpPath() { | ||
return tmpPath; | ||
} | ||
|
||
public Path getFinalPath() { | ||
return finalPath; | ||
} | ||
|
||
} | ||
|
||
public static void main(String[] args) throws Exception { | ||
new IntegrationRunner(new LocalJsonDestination()).run(args); | ||
} | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
airbyte-integrations/connectors/destination-local-json/src/main/resources/spec.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"documentationUrl": "https://docs.airbyte.io/integrations/destinations/local-json", | ||
"supportsIncremental": true, | ||
"connectionSpecification": { | ||
"$schema": "http://json-schema.org/draft-07/schema#", | ||
"title": "Local Json Destination Spec", | ||
"type": "object", | ||
"required": ["destination_path"], | ||
"additionalProperties": false, | ||
"properties": { | ||
"destination_path": { | ||
"description": "Path to the directory where json files will be written. The files will be placed inside that local mount. For more information check out our <a href=\"https://docs.airbyte.io/integrations/destinations/local-json\">docs</a>", | ||
"type": "string", | ||
"examples": ["/json_data"] | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This path should match what we're doing in local csv.
I'm fine with just putting it in a relative directory to the mount (and requiring no preceding slash) or doing it how we do it in local-csv where we require it to start with
/local/
). Either way is fine if it matches.This is how it's defined in local-csv: