Is there any way to send a media file as part of a request in Spring Boot? - request

I am new in programming and seeking for a solution to my problem. Here, I am going to describe my problem in as much clarity as I can.
So, I am working on a problem where I have to create an API which is going to accept (String1, String2, Mediafile(mp3), Mediafile(txt)) and then I have to upload these files somewhere else.
Here, I want to know do we expect Media Files in the byte[] format or is there any way that I can get that Mediafile as it is(Not in Byte format).
package com.self.projects;
import java.io.IOException;
import org.springframework.boot.json.JsonParseException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
#RestController
#RequestMapping("/hellomedia")
public class TestMediafile {
#RequestMapping(value = "addDetails", method = RequestMethod.POST , consumes = "multipart/form-data")
public StudentClassReport addProduct(
#RequestParam String studentReportJson,
#RequestParam MultipartFile report,
#RequestParam MultipartFile transcription,
#RequestParam int marks) throws JsonParseException, JsonMappingException, IOException {
studentClassReport studentReport = new objectMapper().readValue(studentReportJson, StudentClassReport.class);
byte[] myReport = report.getBytes();
byte[] myTranscription = transcription.getBytes();
studentReport.setTranscription(myTranscription);
studentReport.setReport(myReport);
return studentReport;
}
}

Related

How to update a property of an object/entity when a button click occurs in Springboot & React

I'm facing a problem which I cannot seem to resolve.
I have an entity which has a property (specifically a string) with a value of 'In magazijn':
package com.Code.Pakket.management.model;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.jpa.repository.Modifying;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
//Men maakt een JPA entity class zodat hibernate met onze data kan werken.
#Entity
public class Pakketje {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private int code;
private String status ="In magazijn";
public Pakketje() {
}
I would like this string to change when a button click occurs in the react application. The specific object from which the value should be changed is already existing inside of the database, and only the value "In magazijn" should be changed to "Onderweg". This value should change inside of the database.
I have tried the following inside of the service class:
#Override
public String StatusOnderweg(Pakketje pakketje) {
return pakketjeRepository.save(pakketje.setStatus("Onderweg"));
}
So "Pakketje pakketje" is the object of which the string should be changed. I thought about saving the specific object once more to the database (even tough the object already exists) and save it with another string.
My Repository:
package com.Code.Pakket.management.repository;
import com.Code.Pakket.management.model.Pakketje;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
//https://www.javadevjournal.com/spring-boot/spring-boot-with-hibernate/ -- Punt5.
#Repository
public interface PakketjeRepository extends JpaRepository<Pakketje,Integer> {
}
I just don't have an idea how to make this code with a repository, service and controller structure... Any advice?
Thanks in advance.

How to decode base64 string before use in camel context?

I'm using a bean in my Camel Context with the class org.apache.commons.configuration.DatabaseConfiguration to get as key-value the properties saved in my DB. So, the values coming in base64, and I need to decode the values to use them on my routes. How can I do it?
Like Ocp and Kubernetes tools do it inside . It is transferred to the application by decoding the encoded text. You can still do this in camel. this example about encrypt and decrypt using jasypt lib from camel book. you must implement a basic PropertiesParser.class for base64 . PropertiesParser a basic a interface . full example https://github.com/camelinaction/camelinaction2/blob/master/chapter14/configuration/src/test/java/camelinaction/SecuringConfigTest.java
JasyptPropertiesParser jasypt = new JasyptPropertiesParser();
// and set the master password
jasypt.setPassword("supersecret");
// we can avoid keeping the master password in plaintext in the application
// by referencing a environment variable
// export CAMEL_ENCRYPTION_PASSWORD=supersecret
// jasypt.setPassword("sysenv:CAMEL_ENCRYPTION_PASSWORD");
// setup the properties component to use the production file
PropertiesComponent prop = context.getComponent("properties", PropertiesComponent.class);
prop.setLocation("classpath:rider-test.properties");
// and use the jasypt properties parser so we can decrypt values
prop.setPropertiesParser(jasypt);
return context;
You could try using Base64 Decoder from java.util package and use it with bean, exchange function or processor. Use Base64.getDecoder() or Base64.getUrlDecoder() to obtain decoder then use the decoder to decode base64 string to byte array which you can then convert to String with camels .convertBodyTo(String.class) or just creating a new instance with new String(bytes, StandardCharsets.UTF_8);
package com.example;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Base64.Decoder;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;
public class Base64tests extends CamelTestSupport {
#Test
public void Test() throws Exception {
MockEndpoint resultMockEndpoint = getMockEndpoint("mock:result");
resultMockEndpoint.expectedMessageCount(1);
resultMockEndpoint.message(0).body().isEqualTo("Hello World");
template.sendBody("direct:decodeBase64", "SGVsbG8gV29ybGQ=");
resultMockEndpoint.assertIsSatisfied();
}
#Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder(){
#Override
public void configure() throws Exception {
from("direct:decodeBase64")
.routeId("decodeBase64")
.bean(new Base64Decoder())
.log("${body}")
.convertBodyTo(String.class)
.to("mock:result");
}
};
}
}
class Base64Decoder{
public byte[] decode(String encodedValue){
return Base64.getDecoder().decode(encodedValue);
}
}
Using exchange function:
.setBody().exchange( e -> {
String encodedBody = e.getMessage()
.getBody(String.class);
return Base64.getDecoder()
.decode(encodedBody);
})

Datastore export logic in Java

Thankfully, Google announced the export logic from cloud Datastore. I would like to set up schedule-export in my platform. However, it's not Python, but Java. So I need to use cron.xml and Java logic to design this logic.
Is there any reference to design Datastore export logic (cloud_datastore_admin.py) in Java? Especially, I need to transform this part in Java
app = webapp2.WSGIApplication(
[
('/cloud-datastore-export', Export),
], debug=True)
https://cloud.google.com/datastore/docs/schedule-export
You can create the skeleton for App Egnine by following these instructions.
Once you have the skeleton, add something like this to handle export requests:
CloudDatastoreExport.java
package com.google.example.datastore;
import com.google.appengine.api.appidentity.AppIdentityService;
import com.google.appengine.api.appidentity.AppIdentityServiceFactory;
import com.google.apphosting.api.ApiProxy;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Logger;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
#WebServlet(name = "CloudDatastoreExport", value = "/cloud-datastore-export")
public class CloudDatastoreExport extends HttpServlet {
private static final Logger log = Logger.getLogger(CloudDatastoreExport.class.getName());
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// Verify outputURL parameter
String outputUrlPrefix = request.getParameter("output_url_prefix");
if (outputUrlPrefix == null || !outputUrlPrefix.matches("^gs://.*")) {
response.setStatus(HttpServletResponse.SC_CONFLICT);
response.setContentType("text/plain");
response.getWriter().println("Error: Must provide a valid output_url_prefix.");
} else {
// Get project ID
String projectId = ApiProxy.getCurrentEnvironment().getAppId();
// Remove partition information to get plain app ID
String appId = projectId.replaceFirst("(.*~)", "");
// Get access token
ArrayList<String> scopes = new ArrayList<String>();
scopes.add("https://www.googleapis.com/auth/datastore");
final AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService();
final AppIdentityService.GetAccessTokenResult accessToken =
appIdentity.getAccessToken(scopes);
// Read export parameters
// If output prefix does not end with slash, add a timestamp
if (!outputUrlPrefix.substring(outputUrlPrefix.length() - 1).contentEquals("/")) {
String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
outputUrlPrefix = outputUrlPrefix + "/" + timeStamp + "/";
}
String[] namespaces = request.getParameterValues("namespace_id");
String[] kinds = request.getParameterValues("kind");
// Build export request
JSONObject exportRequest = new JSONObject();
exportRequest.put("output_url_prefix", outputUrlPrefix);
JSONObject entityFilter = new JSONObject();
if (kinds != null) {
JSONArray kindsJSON = new JSONArray(kinds);
entityFilter.put("kinds", kinds);
}
if (namespaces != null) {
JSONArray namespacesJSON = new JSONArray(namespaces);
entityFilter.put("namespaceIds", namespacesJSON);
}
exportRequest.put("entityFilter", entityFilter);
URL url = new URL("https://datastore.googleapis.com/v1/projects/" + appId + ":export");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Authorization", "Bearer " + accessToken.getAccessToken());
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
exportRequest.write(writer);
writer.close();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
JSONTokener exportResponseTokens = new JSONTokener(connection.getInputStream());
JSONObject exportResponse = new JSONObject(exportResponseTokens);
response.setContentType("text/plain");
response.getWriter().println("Export started:\n" + exportResponse.toString(4));
} else {
InputStream s = connection.getErrorStream();
InputStreamReader r = new InputStreamReader(s, StandardCharsets.UTF_8);
String errorMessage =
String.format(
"got error (%d) response %s from %s",
connection.getResponseCode(), CharStreams.toString(r), connection.toString());
log.warning(errorMessage);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setContentType("text/plain");
response.getWriter().println("Failed to initiate export.");
}
}
}
}
You can use the same cron.yaml from the docs:
cron:
- description: "Daily Cloud Datastore Export"
url: /cloud-datastore-export?namespace_id=&output_url_prefix=gs://BUCKET_NAME[/NAMESPACE_PATH]
target: cloud-datastore-admin
schedule: every 24 hours
Use gcloud to deploy the cron job:
gcloud app deploy cron.yaml
Make sure you complete this part to give GAE export and bucket permissions or else
you'll get permission denied errors:
https://cloud.google.com/datastore/docs/schedule-export#before_you_begin
The code snippet you showed is just a part of the typical GAE app skeleton specific for 1st generation standard environment python apps. You can easily recognize it in the main.py section of the python quickstart Hello World code review.
The code initializes the app variable (from the main python module, i.e. the main.py file) which is referenced in the app.yaml handler config as script: main.app.
The corresponding java app skeleton is significantly different, see the java quickstart Hello World code review. But no worries, you shouldn't need to specifically transform that code snippet, you just need to build your java app skeleton and focus on what the app handler actually does - making those POST requests to the datastore. Sorry I can't help more, but I'm not a java user.
What I really realized is that app.yaml is like Web.xml in java
and cloud-datastore-export is a servlet that communicates with gae to export data but I can't do more

API Call from App Engine flexible to Firebase FCM failed

API Calls,e.g. to Firebase https://fcm.googleapis.com/fcm/send worked before switching from <env>vm</env> appengine-web.xml to
env: flex app.yaml flexible.
When deploying with mvn appengine:deploy everything is fine, but when an API call gets fired, which worked before, i get the exception below:
Exception in thread "Thread-14" com.google.apphosting.api.ApiProxy$CallNotFoundException:
Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager
at com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:800)
at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:112)
at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:40)
at com.google.api.client.extensions.appengine.http.UrlFetchRequest.execute(UrlFetchRequest.java:74)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981)
at com.qweez.flexenv.service.GameCounterService.run(GameCounterService.java:80)
it crashes when calling request.execute() below:
import com.google.api.client.http.ByteArrayContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
// stuff
try {
HttpRequest request = HttpRequestUtil.getHttpRequestFactory().buildPostRequest(new GenericUrl(GlobalConfig.MESSAGING_SERVER_URL), ByteArrayContent.fromString("application/json", requestBody));
HttpResponse response = request.execute();
//logger.warning(LOG_TAG+" ++++++ response status=" + response.getContent());
} catch (IOException e) {
logger.warning(LOG_TAG+" sent messge to topic error: " + e.getMessage());
}
the helper class httpRequestUtil looks like this
import com.google.api.client.extensions.appengine.http.UrlFetchTransport;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import java.io.IOException;
public class HttpRequestUtil {
private static HttpTransport httpTransport;
private static HttpRequestFactory requestFactory;
static {
httpTransport = UrlFetchTransport.getDefaultInstance();
requestFactory = httpTransport.createRequestFactory(new HttpRequestInitializer() {
#Override
public void initialize(com.google.api.client.http.HttpRequest httpRequest) throws IOException {
HttpHeaders hh = new HttpHeaders();
hh.setAuthorization(GlobalConfig.SERVER_KEY);
hh.setContentType("application/json");
httpRequest.setHeaders(hh);
}
});
}
public static HttpRequestFactory getHttpRequestFactory(){
return requestFactory;
}
Is there something deprecated now?
Or what's the issue here now?
Any help very appreciated. Thanks!

Cant configure my desktop application to Google Calendar API

I am trying to set up my project to use the Google Calendar API. So far I have downloaded the latest libraries and imported them. At the moment I am trying to follow the tutorial from the Google developers which is found here.
From what I found out according to this link draft10 has been deprecated and I am trying to use other classes
which do not belong to draft10.
The following are my current imports:
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.auth.oauth2.AuthorizationCodeTokenRequest;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.googleapis.batch.BatchRequest;
import com.google.api.client.googleapis.batch.json.JsonBatchCallback;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.DateTime;
import com.google.api.client.util.Lists;
import com.google.api.client.util.store.DataStoreFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.calendar.model.Calendar;
import com.google.api.services.calendar.model.CalendarList;
import com.google.api.services.calendar.model.CalendarListEntry;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventDateTime;
import com.google.api.services.calendar.model.Events;
And the following is the method taken from the Google sample with some changes:
public void setUp() throws IOException {
httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
// The clientId and clientSecret can be found in Google Developers Console
String clientId = "YOUR_CLIENT_ID";
String clientSecret = "YOUR_CLIENT_SECRET";
// Or your redirect URL for web based applications.
String redirectUrl = "urn:ietf:wg:oauth:2.0:oob";
ArrayList<String> scopes = new ArrayList<String>();
scopes.add("https://www.googleapis.com/auth/calendar");
// Step 1: Authorize -->
String authorizationUrl = new GoogleAuthorizationCodeRequestUrl(clientId, redirectUrl, scopes)
.build();
// Point or redirect your user to the authorizationUrl.
System.out.println("Go to the following link in your browser:");
System.out.println(authorizationUrl);
// Read the authorization code from the standard input stream.
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("What is the authorization code?");
String code = in.readLine();
// End of Step 1 <--
// Step 2: Exchange -->
GoogleTokenResponse response = new GoogleAuthorizationCodeTokenRequest(httpTransport, jsonFactory,
clientId, clientSecret, code, redirectUrl).execute();
// End of Step 2 <--
GoogleAccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(
response.accessToken, httpTransport, jsonFactory, clientId, clientSecret,
response.refreshToken);
Calendar service = new Calendar(httpTransport, accessProtectedResource, jsonFactory);
service.setApplicationName("YOUR_APPLICATION_NAME");
}
The only problem is with the GoogleAccessProtectedResource class. It is giving me the following error: GoogleAccessProtectedResource cannot be resolved to a type.
Does anyone have any ideas on how I can get around this?
I managed to figure this out. All I had to do was to import the following packages:
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.plus.Plus;
import com.google.api.services.plus.PlusScopes;
And replace the following code:
GoogleAccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(
response.accessToken, httpTransport, jsonFactory, clientId, clientSecret,
response.refreshToken);
Calendar service = new Calendar(httpTransport, accessProtectedResource, jsonFactory);
service.setApplicationName("YOUR_APPLICATION_NAME");
With this code:
GoogleCredential credential;
credential = new GoogleCredential.Builder().setTransport(httpTransport)
.setJsonFactory(jsonFactory).setServiceAccountId("[[INSERT SERVICE ACCOUNT EMAIL HERE]]")
.setServiceAccountScopes(Collections.singleton(PlusScopes.PLUS_ME))
.setServiceAccountPrivateKeyFromP12File(new File("key.p12"))
.build();
Plus plus = new Plus.Builder(httpTransport, jsonFactory, credential)
.setApplicationName("YOUR_APPLICATION_NAME")
.build();

Resources