Skip to content

Commit

Permalink
Feature/28796 data url schema (#683)
Browse files Browse the repository at this point in the history
* add DataUrl

* change json schema from string(json) to data url for Sampling API and Topic Filter API

* fix endpoints

* add license headers

* update openapi
  • Loading branch information
DC2-DanielKrueger authored Dec 10, 2024
1 parent f7ce4b5 commit e97e990
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 14 deletions.
1 change: 1 addition & 0 deletions ext/hivemq-edge-openapi-2024.8-SNAPSHOT.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5996,6 +5996,7 @@ components:
description: The name for this topic filter.
schema:
type: string
format: data-url
description: The optional json schema for this topic filter in the data
uri format.
topicFilter:
Expand Down
117 changes: 117 additions & 0 deletions hivemq-edge/src/main/java/com/hivemq/api/format/DataUrl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright 2019-present HiveMQ GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hivemq.api.format;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

@JsonSerialize(using = DataUrl.Serializer.class)
public class DataUrl {

public static final String BASE64_TOKEN = ";base64";

private final @NotNull String mimeType;
private final @NotNull String encoding;
private final @NotNull String charset;
private final @NotNull String data;

DataUrl(
final @NotNull String mimeType,
final @NotNull String charSet,
final @NotNull String encoding,
final @NotNull String data) {
this.mimeType = mimeType;
this.charset = charSet;
this.encoding = encoding;
this.data = data;
}

public static @NotNull DataUrl createBase64JsonDataUrl(final @NotNull String data) {
return new DataUrl("application/json", StandardCharsets.US_ASCII.displayName(), "base64", data);
}


public static @NotNull DataUrl create(final @NotNull String dataUrlAsString) {
// remove data:
final String dataUrlWithoutDataPrefix = dataUrlAsString.substring(5);
// split meta data and data on the ','
final String[] metaDataAndDataSplit = dataUrlWithoutDataPrefix.split(",");
if (metaDataAndDataSplit.length != 2) {
throw new IllegalArgumentException(dataUrlAsString +
" is not a valid data URL, because it did not contain metadata and data separated by exactly one ','.");
}
final String metadata = metaDataAndDataSplit[0];
final String data = metaDataAndDataSplit[1];
if (!metadata.contains(BASE64_TOKEN)) {
throw new IllegalArgumentException("Only base64 encoding is allowed for data URLs.");
}
final String metaDataWithoutEncoding = metadata.replaceAll(BASE64_TOKEN, "");
if (metaDataWithoutEncoding.contains(";charset=")) {
final String[] mimeAndCharSetSplit = metaDataWithoutEncoding.split(";charset=");
final String mimeType = mimeAndCharSetSplit[0];
final String charset = mimeAndCharSetSplit[1];
return new DataUrl(mimeType, charset, "base64", data);
} else {
return new DataUrl(metaDataWithoutEncoding, StandardCharsets.US_ASCII.displayName(), "base64", data);
}
}


public @NotNull String getCharset() {
return charset;
}

public @NotNull String getData() {
return data;
}

public @NotNull String getEncoding() {
return encoding;
}

public @NotNull String getMimeType() {
return mimeType;
}

@Override
public @NotNull String toString() {
return "data:" + mimeType + ";" + encoding + "," + data;
}


public static class Serializer extends StdSerializer<DataUrl> {

public Serializer() {
this(null);
}

public Serializer(final @NotNull Class<DataUrl> t) {
super(t);
}

@Override
public void serialize(final DataUrl value, final JsonGenerator gen, final SerializerProvider provider)
throws IOException {
gen.writeString(value.toString());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.hivemq.persistence.topicfilter.TopicFilter;
import io.swagger.v3.oas.annotations.media.Schema;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;

Expand All @@ -38,7 +38,7 @@ public class TopicFilterModel {
private final @NotNull String description;

@JsonProperty("schema")
@Schema(description = "The optional json schema for this topic filter in the data uri format.")
@Schema(description = "The optional json schema for this topic filter in the data uri format.", format = "data-url")
private final @Nullable String schema;


Expand Down Expand Up @@ -66,20 +66,24 @@ public TopicFilterModel(

@Override
public boolean equals(final @Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

final TopicFilterModel that = (TopicFilterModel) o;
return topicFilter.equals(that.topicFilter) &&
description.equals(that.description) &&
schema.equals(that.schema);
Objects.equals(schema, that.schema);
}

@Override
public int hashCode() {
int result = topicFilter.hashCode();
result = 31 * result + description.hashCode();
result = 31 * result + schema.hashCode();
result = 31 * result + Objects.hashCode(schema);
return result;
}

Expand All @@ -99,6 +103,8 @@ public int hashCode() {
}

public static @NotNull TopicFilterModel fromTopicFilter(final @NotNull TopicFilter topicFilter) {
return new TopicFilterModel(topicFilter.getTopicFilter(), topicFilter.getDescription(), topicFilter.getSchema());
return new TopicFilterModel(topicFilter.getTopicFilter(),
topicFilter.getDescription(),
topicFilter.getSchema() != null ? topicFilter.getSchema().toString() : null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.hivemq.adapter.sdk.api.writing.WritingProtocolAdapter;
import com.hivemq.api.AbstractApi;
import com.hivemq.api.adapters.AdapterConfigModel;
import com.hivemq.api.format.DataUrl;
import com.hivemq.api.json.CustomConfigSchemaGenerator;
import com.hivemq.api.model.ApiConstants;
import com.hivemq.api.model.ApiErrorMessages;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.hivemq.persistence.topicfilter;

import com.hivemq.api.format.DataUrl;
import com.hivemq.api.model.topicFilters.TopicFilterModel;
import com.hivemq.extension.sdk.api.annotations.Immutable;
import org.jetbrains.annotations.NotNull;
Expand All @@ -25,19 +26,21 @@ public class TopicFilter {

private final @NotNull String description;
private final @NotNull String topicFilter;
private final @Nullable String schema;
private final @Nullable DataUrl schema;


public TopicFilter(
final @NotNull String topicFilter, final @NotNull String description, final @Nullable String schema) {
final @NotNull String topicFilter, final @NotNull String description, final @Nullable DataUrl schema) {
this.description = description;
this.topicFilter = topicFilter;
this.schema = schema;
}

public static @NotNull TopicFilter fromTopicFilterModel(
final @NotNull TopicFilterModel topicFilter) {
return new TopicFilter(topicFilter.getTopicFilter(), topicFilter.getDescription(), topicFilter.getSchema());
return new TopicFilter(topicFilter.getTopicFilter(),
topicFilter.getDescription(),
topicFilter.getSchema() != null ? DataUrl.create(topicFilter.getSchema()) : null);
}

public @NotNull String getDescription() {
Expand All @@ -48,7 +51,7 @@ public TopicFilter(
return topicFilter;
}

public @Nullable String getSchema() {
public @Nullable DataUrl getSchema() {
return schema;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.hivemq.persistence.topicfilter;

import com.hivemq.api.format.DataUrl;
import com.hivemq.persistence.topicfilter.xml.TopicFilterXmlEntity;
import org.jetbrains.annotations.NotNull;

Expand All @@ -23,12 +24,12 @@ public class TopicFilterMapper {
public static @NotNull TopicFilter topicFilterFromDomainTagEntity(final @NotNull TopicFilterXmlEntity topicFilterXmlEntity) {
return new TopicFilter(topicFilterXmlEntity.getTopicFilter(),
topicFilterXmlEntity.getDescription(),
topicFilterXmlEntity.getSchema());
topicFilterXmlEntity.getSchema() != null ? DataUrl.create(topicFilterXmlEntity.getSchema()) : null);
}

public static @NotNull TopicFilterXmlEntity topicFilterEntityFromDomainTag(final @NotNull TopicFilter topicFilter) {
return new TopicFilterXmlEntity(topicFilter.getTopicFilter(),
topicFilter.getDescription(),
topicFilter.getSchema());
topicFilter.getSchema() != null ? topicFilter.getSchema().toString() : null);
}
}
61 changes: 61 additions & 0 deletions hivemq-edge/src/test/java/com/hivemq/api/format/DataUrlTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2019-present HiveMQ GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hivemq.api.format;

import org.junit.jupiter.api.Test;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

class DataUrlTest {

@Test
void test_parse_real_example() {
final String dataUrlAsString =
"data:application/json;base64,IHsKICAgICJ0eXBlIiA6ICJvYmplY3QiLAogICAgInByb3BlcnRpZXMiIDogewogICAgICAiZGVmaW5pdGlvbiIgOiB7CiAgICAgICAgInR5cGUiIDogIm9iamVjdCIsCiAgICAgICAgInByb3BlcnRpZXMiIDogewogICAgICAgICAgImRhdGFUeXBlIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogInN0cmluZyIsCiAgICAgICAgICAgICJlbnVtIiA6IFsgIk5VTEwiLCAiQk9PTCIsICJCWVRFIiwgIldPUkQiLCAiRFdPUkQiLCAiTFdPUkQiLCAiVVNJTlQiLCAiVUlOVCIsICJVRElOVCIsICJVTElOVCIsICJTSU5UIiwgIklOVCIsICJESU5UIiwgIkxJTlQiLCAiUkVBTCIsICJMUkVBTCIsICJDSEFSIiwgIldDSEFSIiwgIlNUUklORyIsICJXU1RSSU5HIiwgIlRJTUUiLCAiTFRJTUUiLCAiREFURSIsICJMREFURSIsICJUSU1FX09GX0RBWSIsICJMVElNRV9PRl9EQVkiLCAiREFURV9BTkRfVElNRSIsICJMREFURV9BTkRfVElNRSIsICJSQVdfQllURV9BUlJBWSIgXSwKICAgICAgICAgICAgInRpdGxlIiA6ICJEYXRhIFR5cGUiLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iIDogIlRoZSBleHBlY3RlZCBkYXRhIHR5cGUgb2YgdGhlIHRhZyIsCiAgICAgICAgICAgICJlbnVtTmFtZXMiIDogWyAiTnVsbCIsICJCb29sZWFuIiwgIkJ5dGUiLCAiV29yZCAodW5pdCAxNikiLCAiRFdvcmQgKHVpbnQgMzIpIiwgIkxXb3JkICh1aW50IDY0KSIsICJVU2ludCAodWludCA4KSIsICJVaW50ICh1aW50IDE2KSIsICJVRGludCAodWludCAzMikiLCAiVUxpbnQgKHVpbnQgNjQpIiwgIlNpbnQgKGludCA4KSIsICJJbnQgKGludCAxNikiLCAiRGludCAoaW50IDMyKSIsICJMaW50IChpbnQgNjQpIiwgIlJlYWwgKGZsb2F0IDMyKSIsICJMUmVhbCAoZG91YmxlIDY0KSIsICJDaGFyICgxIGJ5dGUgY2hhcikiLCAiV0NoYXIgKDIgYnl0ZSBjaGFyKSIsICJTdHJpbmciLCAiV1N0cmluZyIsICJUaW1pbmcgKER1cmF0aW9uIG1zKSIsICJMb25nIFRpbWluZyAoRHVyYXRpb24gbnMpIiwgIkRhdGUgKERhdGVTdGFtcCkiLCAiTG9uZyBEYXRlIChEYXRlU3RhbXApIiwgIlRpbWUgT2YgRGF5IChUaW1lU3RhbXApIiwgIkxvbmcgVGltZSBPZiBEYXkgKFRpbWVTdGFtcCkiLCAiRGF0ZSBUaW1lIChEYXRlVGltZVN0YW1wKSIsICJMb25nIERhdGUgVGltZSAoRGF0ZVRpbWVTdGFtcCkiLCAiUmF3IEJ5dGUgQXJyYXkiIF0KICAgICAgICAgIH0sCiAgICAgICAgICAidGFnQWRkcmVzcyIgOiB7CiAgICAgICAgICAgICJ0eXBlIiA6ICJzdHJpbmciLAogICAgICAgICAgICAidGl0bGUiIDogIlRhZyBBZGRyZXNzIiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIiA6ICJUaGUgd2VsbCBmb3JtZWQgYWRkcmVzcyBvZiB0aGUgdGFnIHRvIHJlYWQiCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicmVxdWlyZWQiIDogWyAiZGF0YVR5cGUiLCAidGFnQWRkcmVzcyIgXSwKICAgICAgICAidGl0bGUiIDogImRlZmluaXRpb24iLAogICAgICAgICJkZXNjcmlwdGlvbiIgOiAiVGhlIGFjdHVhbCBkZWZpbml0aW9uIG9mIHRoZSB0YWcgb24gdGhlIGRldmljZSIKICAgICAgfSwKICAgICAgImRlc2NyaXB0aW9uIiA6IHsKICAgICAgICAidHlwZSIgOiAic3RyaW5nIiwKICAgICAgICAidGl0bGUiIDogImRlc2NyaXB0aW9uIiwKICAgICAgICAiZGVzY3JpcHRpb24iIDogIkEgaHVtYW4gcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhlIHRhZyIKICAgICAgfSwKICAgICAgIm5hbWUiIDogewogICAgICAgICJ0eXBlIiA6ICJzdHJpbmciLAogICAgICAgICJ0aXRsZSIgOiAibmFtZSIsCiAgICAgICAgImRlc2NyaXB0aW9uIiA6ICJuYW1lIG9mIHRoZSB0YWcgdG8gYmUgdXNlZCBpbiBtYXBwaW5ncyIKICAgICAgfQogICAgfSwKICAgICJyZXF1aXJlZCIgOiBbICJkZWZpbml0aW9uIiwgImRlc2NyaXB0aW9uIiwgIm5hbWUiIF0KICB9Cg==";
final DataUrl dataUrl = DataUrl.create(dataUrlAsString);
assertEquals("application/json", dataUrl.getMimeType());
assertEquals("US-ASCII", dataUrl.getCharset());
assertEquals("base64", dataUrl.getEncoding());
assertEquals(
"IHsKICAgICJ0eXBlIiA6ICJvYmplY3QiLAogICAgInByb3BlcnRpZXMiIDogewogICAgICAiZGVmaW5pdGlvbiIgOiB7CiAgICAgICAgInR5cGUiIDogIm9iamVjdCIsCiAgICAgICAgInByb3BlcnRpZXMiIDogewogICAgICAgICAgImRhdGFUeXBlIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogInN0cmluZyIsCiAgICAgICAgICAgICJlbnVtIiA6IFsgIk5VTEwiLCAiQk9PTCIsICJCWVRFIiwgIldPUkQiLCAiRFdPUkQiLCAiTFdPUkQiLCAiVVNJTlQiLCAiVUlOVCIsICJVRElOVCIsICJVTElOVCIsICJTSU5UIiwgIklOVCIsICJESU5UIiwgIkxJTlQiLCAiUkVBTCIsICJMUkVBTCIsICJDSEFSIiwgIldDSEFSIiwgIlNUUklORyIsICJXU1RSSU5HIiwgIlRJTUUiLCAiTFRJTUUiLCAiREFURSIsICJMREFURSIsICJUSU1FX09GX0RBWSIsICJMVElNRV9PRl9EQVkiLCAiREFURV9BTkRfVElNRSIsICJMREFURV9BTkRfVElNRSIsICJSQVdfQllURV9BUlJBWSIgXSwKICAgICAgICAgICAgInRpdGxlIiA6ICJEYXRhIFR5cGUiLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iIDogIlRoZSBleHBlY3RlZCBkYXRhIHR5cGUgb2YgdGhlIHRhZyIsCiAgICAgICAgICAgICJlbnVtTmFtZXMiIDogWyAiTnVsbCIsICJCb29sZWFuIiwgIkJ5dGUiLCAiV29yZCAodW5pdCAxNikiLCAiRFdvcmQgKHVpbnQgMzIpIiwgIkxXb3JkICh1aW50IDY0KSIsICJVU2ludCAodWludCA4KSIsICJVaW50ICh1aW50IDE2KSIsICJVRGludCAodWludCAzMikiLCAiVUxpbnQgKHVpbnQgNjQpIiwgIlNpbnQgKGludCA4KSIsICJJbnQgKGludCAxNikiLCAiRGludCAoaW50IDMyKSIsICJMaW50IChpbnQgNjQpIiwgIlJlYWwgKGZsb2F0IDMyKSIsICJMUmVhbCAoZG91YmxlIDY0KSIsICJDaGFyICgxIGJ5dGUgY2hhcikiLCAiV0NoYXIgKDIgYnl0ZSBjaGFyKSIsICJTdHJpbmciLCAiV1N0cmluZyIsICJUaW1pbmcgKER1cmF0aW9uIG1zKSIsICJMb25nIFRpbWluZyAoRHVyYXRpb24gbnMpIiwgIkRhdGUgKERhdGVTdGFtcCkiLCAiTG9uZyBEYXRlIChEYXRlU3RhbXApIiwgIlRpbWUgT2YgRGF5IChUaW1lU3RhbXApIiwgIkxvbmcgVGltZSBPZiBEYXkgKFRpbWVTdGFtcCkiLCAiRGF0ZSBUaW1lIChEYXRlVGltZVN0YW1wKSIsICJMb25nIERhdGUgVGltZSAoRGF0ZVRpbWVTdGFtcCkiLCAiUmF3IEJ5dGUgQXJyYXkiIF0KICAgICAgICAgIH0sCiAgICAgICAgICAidGFnQWRkcmVzcyIgOiB7CiAgICAgICAgICAgICJ0eXBlIiA6ICJzdHJpbmciLAogICAgICAgICAgICAidGl0bGUiIDogIlRhZyBBZGRyZXNzIiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIiA6ICJUaGUgd2VsbCBmb3JtZWQgYWRkcmVzcyBvZiB0aGUgdGFnIHRvIHJlYWQiCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicmVxdWlyZWQiIDogWyAiZGF0YVR5cGUiLCAidGFnQWRkcmVzcyIgXSwKICAgICAgICAidGl0bGUiIDogImRlZmluaXRpb24iLAogICAgICAgICJkZXNjcmlwdGlvbiIgOiAiVGhlIGFjdHVhbCBkZWZpbml0aW9uIG9mIHRoZSB0YWcgb24gdGhlIGRldmljZSIKICAgICAgfSwKICAgICAgImRlc2NyaXB0aW9uIiA6IHsKICAgICAgICAidHlwZSIgOiAic3RyaW5nIiwKICAgICAgICAidGl0bGUiIDogImRlc2NyaXB0aW9uIiwKICAgICAgICAiZGVzY3JpcHRpb24iIDogIkEgaHVtYW4gcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhlIHRhZyIKICAgICAgfSwKICAgICAgIm5hbWUiIDogewogICAgICAgICJ0eXBlIiA6ICJzdHJpbmciLAogICAgICAgICJ0aXRsZSIgOiAibmFtZSIsCiAgICAgICAgImRlc2NyaXB0aW9uIiA6ICJuYW1lIG9mIHRoZSB0YWcgdG8gYmUgdXNlZCBpbiBtYXBwaW5ncyIKICAgICAgfQogICAgfSwKICAgICJyZXF1aXJlZCIgOiBbICJkZWZpbml0aW9uIiwgImRlc2NyaXB0aW9uIiwgIm5hbWUiIF0KICB9Cg==",
dataUrl.getData());
assertEquals(dataUrlAsString, dataUrl.toString());
}

@Test
void test_whenBase64Missing_thenException() {
final String dataUrlAsString =
"data:application/json,IHsKICAgICJ0eXBlIiA6ICJvYmplY3QiLAogICAgInByb3BlcnRpZXMiIDogewogICAgICAiZGVmaW5pdGlvbiIgOiB7CiAgICAgICAgInR5cGUiIDogIm9iamVjdCIsCiAgICAgICAgInByb3BlcnRpZXMiIDogewogICAgICAgICAgImRhdGFUeXBlIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogInN0cmluZyIsCiAgICAgICAgICAgICJlbnVtIiA6IFsgIk5VTEwiLCAiQk9PTCIsICJCWVRFIiwgIldPUkQiLCAiRFdPUkQiLCAiTFdPUkQiLCAiVVNJTlQiLCAiVUlOVCIsICJVRElOVCIsICJVTElOVCIsICJTSU5UIiwgIklOVCIsICJESU5UIiwgIkxJTlQiLCAiUkVBTCIsICJMUkVBTCIsICJDSEFSIiwgIldDSEFSIiwgIlNUUklORyIsICJXU1RSSU5HIiwgIlRJTUUiLCAiTFRJTUUiLCAiREFURSIsICJMREFURSIsICJUSU1FX09GX0RBWSIsICJMVElNRV9PRl9EQVkiLCAiREFURV9BTkRfVElNRSIsICJMREFURV9BTkRfVElNRSIsICJSQVdfQllURV9BUlJBWSIgXSwKICAgICAgICAgICAgInRpdGxlIiA6ICJEYXRhIFR5cGUiLAogICAgICAgICAgICAiZGVzY3JpcHRpb24iIDogIlRoZSBleHBlY3RlZCBkYXRhIHR5cGUgb2YgdGhlIHRhZyIsCiAgICAgICAgICAgICJlbnVtTmFtZXMiIDogWyAiTnVsbCIsICJCb29sZWFuIiwgIkJ5dGUiLCAiV29yZCAodW5pdCAxNikiLCAiRFdvcmQgKHVpbnQgMzIpIiwgIkxXb3JkICh1aW50IDY0KSIsICJVU2ludCAodWludCA4KSIsICJVaW50ICh1aW50IDE2KSIsICJVRGludCAodWludCAzMikiLCAiVUxpbnQgKHVpbnQgNjQpIiwgIlNpbnQgKGludCA4KSIsICJJbnQgKGludCAxNikiLCAiRGludCAoaW50IDMyKSIsICJMaW50IChpbnQgNjQpIiwgIlJlYWwgKGZsb2F0IDMyKSIsICJMUmVhbCAoZG91YmxlIDY0KSIsICJDaGFyICgxIGJ5dGUgY2hhcikiLCAiV0NoYXIgKDIgYnl0ZSBjaGFyKSIsICJTdHJpbmciLCAiV1N0cmluZyIsICJUaW1pbmcgKER1cmF0aW9uIG1zKSIsICJMb25nIFRpbWluZyAoRHVyYXRpb24gbnMpIiwgIkRhdGUgKERhdGVTdGFtcCkiLCAiTG9uZyBEYXRlIChEYXRlU3RhbXApIiwgIlRpbWUgT2YgRGF5IChUaW1lU3RhbXApIiwgIkxvbmcgVGltZSBPZiBEYXkgKFRpbWVTdGFtcCkiLCAiRGF0ZSBUaW1lIChEYXRlVGltZVN0YW1wKSIsICJMb25nIERhdGUgVGltZSAoRGF0ZVRpbWVTdGFtcCkiLCAiUmF3IEJ5dGUgQXJyYXkiIF0KICAgICAgICAgIH0sCiAgICAgICAgICAidGFnQWRkcmVzcyIgOiB7CiAgICAgICAgICAgICJ0eXBlIiA6ICJzdHJpbmciLAogICAgICAgICAgICAidGl0bGUiIDogIlRhZyBBZGRyZXNzIiwKICAgICAgICAgICAgImRlc2NyaXB0aW9uIiA6ICJUaGUgd2VsbCBmb3JtZWQgYWRkcmVzcyBvZiB0aGUgdGFnIHRvIHJlYWQiCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicmVxdWlyZWQiIDogWyAiZGF0YVR5cGUiLCAidGFnQWRkcmVzcyIgXSwKICAgICAgICAidGl0bGUiIDogImRlZmluaXRpb24iLAogICAgICAgICJkZXNjcmlwdGlvbiIgOiAiVGhlIGFjdHVhbCBkZWZpbml0aW9uIG9mIHRoZSB0YWcgb24gdGhlIGRldmljZSIKICAgICAgfSwKICAgICAgImRlc2NyaXB0aW9uIiA6IHsKICAgICAgICAidHlwZSIgOiAic3RyaW5nIiwKICAgICAgICAidGl0bGUiIDogImRlc2NyaXB0aW9uIiwKICAgICAgICAiZGVzY3JpcHRpb24iIDogIkEgaHVtYW4gcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhlIHRhZyIKICAgICAgfSwKICAgICAgIm5hbWUiIDogewogICAgICAgICJ0eXBlIiA6ICJzdHJpbmciLAogICAgICAgICJ0aXRsZSIgOiAibmFtZSIsCiAgICAgICAgImRlc2NyaXB0aW9uIiA6ICJuYW1lIG9mIHRoZSB0YWcgdG8gYmUgdXNlZCBpbiBtYXBwaW5ncyIKICAgICAgfQogICAgfSwKICAgICJyZXF1aXJlZCIgOiBbICJkZWZpbml0aW9uIiwgImRlc2NyaXB0aW9uIiwgIm5hbWUiIF0KICB9Cg==";
assertThrows(IllegalArgumentException.class, ()->DataUrl.create(dataUrlAsString));
}


@Test
void test_createBase64JsonDataUrl() {
final DataUrl dataUrl = DataUrl.createBase64JsonDataUrl(Base64.getEncoder()
.encodeToString("HelloWorld".getBytes(StandardCharsets.UTF_8)));
assertEquals("application/json", dataUrl.getMimeType());
assertEquals("US-ASCII", dataUrl.getCharset());
assertEquals("base64", dataUrl.getEncoding());
assertEquals(
"HelloWorld",
new String(Base64.getDecoder().decode(dataUrl.getData().getBytes(StandardCharsets.UTF_8))));
}
}

0 comments on commit e97e990

Please sign in to comment.