I am using an object mapper called Orika, and I have some doubts regarding how it works or am I doing anything wrong here.
Following are the classes
https://googleapis.dev/java/google-cloud-channel/latest/com/google/cloud/channel/v1/Entitlement.html
This is the source class structure, an object comes in this format.
Entitlements.java
#Data
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Entitlement {
private String name;
private String createTime;
private String updateTime;
private String offer;
private String provisioningState;
private ProvisionedService provisionedService;
private String purchaseOrderId;
private List<String> suspensionReasons;
private CommitmentSettings commitmentSettings;
private TrialSettings trialSettings;
private AssociationInfo associationInfo;
private List<Parameter> parameters;
}
Parameter.java
#Data
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Parameter {
private String name;
private Value value;
private boolean editable;
}
My orika mapper code:
public class OrikaMapper {
private MapperFactory mapperFactory;
public <S, D> D map(S s, Class<D> type) {
return this.mapperFactory.getMapperFacade().map(s, type);
}
}
my method:
public Entitlement getEntitlement(String credential, String customerId, String entitlementId) {
CloudChannelServiceClient client = null;
Entitlement resp = null;
try {
client = <<>>;
String name = "accounts/"+ ACCOUNT_ID +"/customers/"+customerId+"/entitlements/"+entitlementId;
GetEntitlementRequest request = GetEntitlementRequest.newBuilder().setName(name).build();
com.google.cloud.channel.v1.Entitlement entitlement = client.getEntitlement(request);
resp = orikaMapper.map(gson.toJson(entitlement), Entitlement.class);
} catch (Exception e) {
throw new ApplicationException("code", e.getMessage());
}
return resp;
}
sample response from google API
{ "name_": "<<>>", "createTime_": { "seconds_": 1615715413, "nanos_": 810000000, "memoizedIsInitialized": -1, "unknownFields": { "fields": {}, "fieldsDescending": {} }, "memoizedSize": -1, "memoizedHashCode": 0 }, "offer_": "<<>>", "provisioningState_": 5, "provisionedService_": { "provisioningId_": "<<>>", "productId_": "<<>>", "skuId_": "<<>>", "memoizedIsInitialized": -1, "unknownFields": { "fields": {}, "fieldsDescending": {} }, "memoizedSize": -1, "memoizedHashCode": 0 }, "suspensionReasons_": [ 4 ], "suspensionReasonsMemoizedSerializedSize": 0, "purchaseOrderId_": "A codelab test", "trialSettings_": { "trial_": false, "memoizedIsInitialized": -1, "unknownFields": { "fields": {}, "fieldsDescending": {} }, "memoizedSize": -1, "memoizedHashCode": 0 }, "parameters_": [ { "name_": "max_units", "value_": { "kindCase_": 1, "kind_": 4, "memoizedIsInitialized": -1, "unknownFields": { "fields": {}, "fieldsDescending": {} }, "memoizedSize": -1, "memoizedHashCode": 0 }, "editable_": true, "memoizedIsInitialized": -1, "unknownFields": { "fields": {}, "fieldsDescending": {} }, "memoizedSize": -1, "memoizedHashCode": 0 }, { "name_": "assigned_units", "value_": { "kindCase_": 1, "kind_": 1, "memoizedIsInitialized": -1, "unknownFields": { "fields": {}, "fieldsDescending": {} }, "memoizedSize": -1, "memoizedHashCode": 0 }, "editable_": false, "memoizedIsInitialized": -1, "unknownFields": { "fields": {}, "fieldsDescending": {} }, "memoizedSize": -1, "memoizedHashCode": 0 } ], "memoizedIsInitialized": -1, "unknownFields": { "fields": {}, "fieldsDescending": {} }, "memoizedSize": -1, "memoizedHashCode": 0 }
Response after mapping in orika
{ "name": "<<>>", "createTime": "seconds: 1615715413\nnanos: 810000000\n", "updateTime": "", "offer": "<<>>", "provisioningState": "SUSPENDED", "provisionedService": { "provisioningId": "<<>>", "productId": "<<>>", "skuId": "<<>>" }, "purchaseOrderId": "A codelab test", "commitmentSettings": { "startTime": "", "endTime": "", "renewalSettings": { "enableRenewal": false, "resizeUnitCount": false, "paymentPlan": "PAYMENT_PLAN_UNSPECIFIED", "paymentCycle": { "duration": 0, "periodType": "PERIOD_TYPE_UNSPECIFIED" } } }, "trialSettings": { "trial": false, "endTime": "" }, "associationInfo": { "baseEntitlement": "" } }
My issue is, the response is not able to map what is in the List<> fields. All the other fields are mapped.
What am i missing here.
Rather late in reply, but if this helps anyone in the future. I was facing the same issue. It seems that you have to explicitly call:
mapper.mapAsList
I.e. in questioner's case:
parameters = orikaMapper.mapAsList(entitlement.getParameters(), Parameter.class);
Related
I am using Opentelemetry collector with below configuration which uses http receiver and export it to logs but when I call the API it returns 200 http code but in the console of collector I don't see any logs.
NOTE: I am using otel/opentelemetry-collector-contrib:0.68.0 Image
collector-config.yaml
receivers:
otlp:
protocols:
http: http://localhost:4318
exporters:
logging:
loglevel: debug
service:
pipelines:
traces:
exporters: [logging]
receivers: [otlp]
metrics:
exporters: [logging]
receivers: [otlp]
logs:
exporters: [logging]
receivers: [otlp]
telemetry:
metrics:
level: detailed
Http Call:
POST: http://localhost:4318/v1/metrics
Request Body
{
"resourceMetrics_": [
{
"resource_": {
"attributes_": [
{
"key_": "loki.attribute.labels",
"value_": {
"valueCase_": 1,
"value_": "http.status",
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
{
"key_": "loki.resource.labels",
"value_": {
"valueCase_": 1,
"value_": "host.name, pod.name",
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
}
],
"droppedAttributesCount_": 0,
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
"scopeMetrics_": [
{
"scope_": {
"name_": "otelcol/hostmetricsreceiver/load",
"version_": "0.68.0",
"attributes_": [],
"droppedAttributesCount_": 0,
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
"metrics_": [
{
"dataCase_": 5,
"data_": {
"dataPoints_": [
{
"valueCase_": 4,
"value_": 0.94,
"attributes_": [
{
"key_": "loki.attribute.labels",
"value_": {
"valueCase_": 1,
"value_": "http.status_code",
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
}
],
"startTimeUnixNano_": 1673933623000000000,
"timeUnixNano_": 1673962743472355755,
"exemplars_": [],
"flags_": 0,
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
}
],
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
"name_": "system.cpu.load_average.15m",
"description_": "Average CPU Load over 15 minutes.",
"unit_": "1",
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
{
"dataCase_": 5,
"data_": {
"dataPoints_": [
{
"valueCase_": 4,
"value_": 0.99,
"attributes_": [
{
"key_": "loki.attribute.labels",
"value_": {
"valueCase_": 1,
"value_": "http.status_code",
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
}
],
"startTimeUnixNano_": 1673933623000000000,
"timeUnixNano_": 1673962743472355755,
"exemplars_": [],
"flags_": 0,
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
}
],
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
"name_": "system.cpu.load_average.1m",
"description_": "Average CPU Load over 1 minute.",
"unit_": "1",
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
{
"dataCase_": 5,
"data_": {
"dataPoints_": [
{
"valueCase_": 4,
"value_": 0.81,
"attributes_": [
{
"key_": "loki.attribute.labels",
"value_": {
"valueCase_": 1,
"value_": "http.status_code",
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
}
],
"startTimeUnixNano_": 1673933623000000000,
"timeUnixNano_": 1673962743472355755,
"exemplars_": [],
"flags_": 0,
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
}
],
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
},
"name_": "system.cpu.load_average.5m",
"description_": "Average CPU Load over 5 minutes.",
"unit_": "1",
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
}
],
"schemaUrl_": "",
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
}
],
"schemaUrl_": "https://opentelemetry.io/schemas/1.9.0",
"memoizedIsInitialized": -1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
}
],
"memoizedIsInitialized": 1,
"unknownFields": {
"fields": {}
},
"memoizedSize": -1,
"memoizedHashCode": 0
}
Collector Logs:
Use older OTLP collector version, which has older OTLP protocol version and you will get error response for your payload:
{
"code": 3,
"message": "unknown field \"unknownFields\" in v1.ExportMetricsServiceRequest"
}
Newer versions ignore unknowns fields silently, so you don't see any error.
Tested with public.ecr.aws/aws-observability/aws-otel-collector:v0.21.0
I have JSON response from spring boot as,
{
"content": [],
"pageable": {
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"offset": 0,
"pageNumber": 0,
"pageSize": 10,
"unpaged": false,
"paged": true
},
"totalPages": 0,
"totalElements": 0,
"last": true,
"size": 10,
"number": 0,
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"numberOfElements": 0,
"first": true,
"empty": true
}
But I need this response as below,
{
"content": [],
"last": true,
"totalPages": 0,
"totalElements": 0,
"size": 10,
"number": 0,
"sort": null,
"first": true,
"numberOfElements": 0
}
in brief, How can I modify the default parameters of returned response? is there any extra configuration I can set for that? thanks in advance
I guess you're using spring data page so just create an implementation of JsonSerializer
eg.
#JsonComponent
public class PageImplJacksonSerializer extends JsonSerializer<PageImpl> {
#Override
public void serialize(PageImpl page, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeObjectField("content", page.getContent());
jsonGenerator.writeBooleanField("first", page.isFirst());
jsonGenerator.writeBooleanField("last", page.isLast());
jsonGenerator.writeNumberField("page_number", page.getNumber());
jsonGenerator.writeNumberField("elements_per_page", page.getNumberOfElements());
jsonGenerator.writeNumberField("total_pages", page.getTotalPages());
jsonGenerator.writeNumberField("total_elements", page.getTotalElements());
jsonGenerator.writeEndObject();
}
}
I have a huge amount of elasticsearch data, I neeed to make aggregations and return buckets. I need to limit data size returned from elasticsearch to only get a sample for the data not all data.
I have tried adding "size" attribute. But it's not acceptable in bucketing aggregations.
{
"size": 0,
"query": {
"bool": {
"adjust_pure_negative": true,
"boost": 1
}
},
"aggregations": {
"my_agg_1": {
"histogram": {
"field": "coAt",
"interval": 86400,
"offset": 1558216800,
"order": {
"_key": "asc"
},
"keyed": false,
"min_doc_count": 1
},
"aggregations": {
"my_agg_2": {
"terms": {
"field": "atr1",
"missing": "NaN",
"value_type": "string",
"size": 2147483647,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
},
"aggregations": {
"atr2": {
"top_hits": {
"from": 0,
"size": 1,
"version": false,
"explain": false,
"sort": [
{
"coAt": {
"order": "desc"
}
}
]
}
},
"clientIP_count": {
"value_count": {
"field": "clientIP"
}
}
}
}
}
}
}
}
I am using spring boot 2 and I like the out of the box featured it had, but now I am being asked to reformat to the paging results to a different structure. I would like to continue to use the Pageable and the Page functionality in the controller. I am looking to the proper way to do this.
From the controller
#GetMapping(name = "customers", produces = MediaType.APPLICATION_JSON_VALUE)
Page<Customer> showCustomers(Pageable pageable) {
Page<Customer> page = customerRepo.findCustomers(pageable);
return page;
}
The repo used
public interface CustomerRepository extends JpaRepository<Customer, Long> {
}
Here is the default format:
{
"content": [
],
"pageable": {
"sort": {
"sorted": false,
"unsorted": true
},
"offset": 0,
"pageSize": 20,
"pageNumber": 0,
"unpaged": false,
"paged": true
},
"last": false,
"totalPages": 62835,
"totalElements": 1256684,
"size": 20,
"number": 0,
"numberOfElements": 20,
"sort": {
"sorted": false,
"unsorted": true
},
"first": true
}
Here is the format that I want
{
"#id": "/users?page=2&page_size=4",
"#type": "Collection",
"#links": {
"first": {
"href": "/users?page=1&page_size=4"
},
"next": {
"href": "/users?page=3&page_size=4"
},
"previous": {
"href": "/users?page=1&page_size=4"
},
"last": {
"href": "/users?page=5&page_size=4"
}
},
"items": [
Content...
],
"total_items": 20
}
I have a magento CE 2.1.2 storefront set up. I'd like to use Java to upload products to my store using the Magento REST API. I have managed to get 2 leg OAuth set up using Apache-commons-httpclient, and product upload actually works quite well. The problem comes when I try to upload an image with the product.
From the official catalogProductRepositoryV1 Magento docs, the json syntax is: (the important part being the "media_gallery_entries" bit)
{
"product": {
"id": 0,
"sku": "string",
"name": "string",
"attribute_set_id": 0,
"price": 0,
"status": 0,
"visibility": 0,
"type_id": "string",
"created_at": "string",
"updated_at": "string",
"weight": 0,
"extension_attributes": {
"bundle_product_options": [
{
"option_id": 0,
"title": "string",
"required": true,
"type": "string",
"position": 0,
"sku": "string",
"product_links": [
{
"id": "string",
"sku": "string",
"option_id": 0,
"qty": 0,
"position": 0,
"is_default": true,
"price": 0,
"price_type": 0,
"can_change_quantity": 0,
"extension_attributes": {}
}
],
"extension_attributes": {}
}
],
"downloadable_product_links": [
{
"id": 0,
"title": "string",
"sort_order": 0,
"is_shareable": 0,
"price": 0,
"number_of_downloads": 0,
"link_type": "string",
"link_file": "string",
"link_file_content": {
"file_data": "string",
"name": "string",
"extension_attributes": {}
},
"link_url": "string",
"sample_type": "string",
"sample_file": "string",
"sample_file_content": {
"file_data": "string",
"name": "string",
"extension_attributes": {}
},
"sample_url": "string",
"extension_attributes": {}
}
],
"downloadable_product_samples": [
{
"id": 0,
"title": "string",
"sort_order": 0,
"sample_type": "string",
"sample_file": "string",
"sample_file_content": {
"file_data": "string",
"name": "string",
"extension_attributes": {}
},
"sample_url": "string",
"extension_attributes": {}
}
],
"stock_item": {
"item_id": 0,
"product_id": 0,
"stock_id": 0,
"qty": 0,
"is_in_stock": true,
"is_qty_decimal": true,
"show_default_notification_message": true,
"use_config_min_qty": true,
"min_qty": 0,
"use_config_min_sale_qty": 0,
"min_sale_qty": 0,
"use_config_max_sale_qty": true,
"max_sale_qty": 0,
"use_config_backorders": true,
"backorders": 0,
"use_config_notify_stock_qty": true,
"notify_stock_qty": 0,
"use_config_qty_increments": true,
"qty_increments": 0,
"use_config_enable_qty_inc": true,
"enable_qty_increments": true,
"use_config_manage_stock": true,
"manage_stock": true,
"low_stock_date": "string",
"is_decimal_divided": true,
"stock_status_changed_auto": 0,
"extension_attributes": {}
},
"configurable_product_options": [
{
"id": 0,
"attribute_id": "string",
"label": "string",
"position": 0,
"is_use_default": true,
"values": [
{
"value_index": 0,
"extension_attributes": {}
}
],
"extension_attributes": {},
"product_id": 0
}
],
"configurable_product_links": [
0
]
},
"product_links": [
{
"sku": "string",
"link_type": "string",
"linked_product_sku": "string",
"linked_product_type": "string",
"position": 0,
"extension_attributes": {
"qty": 0
}
}
],
"options": [
{
"product_sku": "string",
"option_id": 0,
"title": "string",
"type": "string",
"sort_order": 0,
"is_require": true,
"price": 0,
"price_type": "string",
"sku": "string",
"file_extension": "string",
"max_characters": 0,
"image_size_x": 0,
"image_size_y": 0,
"values": [
{
"title": "string",
"sort_order": 0,
"price": 0,
"price_type": "string",
"sku": "string",
"option_type_id": 0
}
],
"extension_attributes": {}
}
],
"media_gallery_entries": [
{
"id": 0,
"media_type": "string",
"label": "string",
"position": 0,
"disabled": true,
"types": [
"string"
],
"file": "string",
"content": {
"base64_encoded_data": "string",
"type": "string",
"name": "string"
},
"extension_attributes": {
"video_content": {
"media_type": "string",
"video_provider": "string",
"video_url": "string",
"video_title": "string",
"video_description": "string",
"video_metadata": "string"
}
}
}
],
"tier_prices": [
{
"customer_group_id": 0,
"qty": 0,
"value": 0,
"extension_attributes": {}
}
],
"custom_attributes": [
{
"attribute_code": "string",
"value": "string"
}
]
},
"saveOptions": true
}
The methods I'm running:
public void uploadItem(ItemType item) throws UploadException {
try {
HttpPost postRequest = new HttpPost("http://my.magento.storefront/index.php/rest/V1/products");
postRequest.addHeader("Content-Type", "application/json");
postRequest.addHeader("Authorization", String.format("Bearer %s", authToken));
String jsonItem = itemToJson(item);
System.out.println(jsonItem);
postRequest.setEntity(new StringEntity(jsonItem));
HttpResponse postResponse = httpClient.execute(postRequest);
System.out.println();
System.out.println(EntityUtils.toString(postResponse.getEntity()));
} catch (ParseException | IOException | JSONException e) {
e.printStackTrace();
throw new UploadException(e);
}
}
private String imagesToJson(ItemType item) throws IOException {
String imageUrl = "http://my.image.jpeg"; //pulled from item in production
String encodedImage = null;
URL url = new URL(imageUrl);
try(InputStream in = new BufferedInputStream(url.openStream());
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] buf = new byte[512];
for (int count = in.read(buf); count >= 0; count = in.read(buf)) {
out.write(buf, 0, count);
}
byte[] response = out.toByteArray(); //sane, I tried saving to a file and checking
encodedImage = Base64.getEncoder().encodeToString(response);
}
String picName = item.getItemID() + ".jpg";
return new JSONArray().put(
new JSONObject()
.put("position", 0)
.put("media_type", "image")
.put("disabled", "false")
.put("types", new JSONArray()
.put("image")
.put("small_image")
.put("thumbnail"))
.put("label", picName)
.put("content", new JSONObject()
.put("base64_encoded_data", encodedImage)
.put("type", "image/jpeg")
.put("name", picName))
).toString();
}
private String itemToJson(ItemType item) throws JSONException, IOException {
return new JSONObject().put("saveOptions", "true").put("product",
new JSONObject()
.put("sku", item.getItemID())
.put("name", item.getTitle())
.put("attribute_set_id", 4)
.put("price", item.getSellingStatus().getCurrentPrice().getValue())
.put("status", 0)
.put("visibility", 0)
.put("type_id", "simple")
.put("weight", item.getShippingDetails().getCalculatedShippingRate().getWeightMajor().getValue())
.put("media_gallery_entries", imagesToJson(item)))
.toString();
}
Using uploadItem(ItemType), the product is uploaded to the catalog. However, there is no image on the store, and I'm given "media_gallery_entries": [] in the response, with no further debugging help!
I think I've implemented everything correctly, so I'm unsure what to do other than SFTP and manually manage the media folder; which just sounds ugly.
Let me know if anyone needs any extra info, or omitted methods/fields.
I solved this by using Gson instead of org.json. I believe the issue was me erroneously using string literals where the server expected otherwise (namely, the boolean values).