Date field change during Retrofit uploads - java

I am using Retrofit2 for upload SOAP request. Date automatically changes during the upload process in 10 out 1000 requests. I have investigated a lot and pin point the issue when I started logging the call with interceptor.
Log Printed before interceptor
fromTime:2018-10-13T13:22:00
isDeleted:false
name:Unknown visitor
reason:Unknown reason
toTime:2018-10-13T23:59:59
vrm:ABC
Log Printed in Interceptor.
FromTime:2018-10-20T11:59:00
Name:Unknown visitor
Reason:Unknown reason
ToTime:2018-10-13T23:59:59
Vrm:ABC
isDeleted:false
It can be seen fromTime:2018-10-13T13:22:00 changes to FromTime:2018-10-20T11:59:00.
Build request is as follow
public EnvelopeSender build() {
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new EnvelopInterceptor()).build();
Retrofit retrofit = new Retrofit.Builder().client(client)
.baseUrl(url)
.addConverterFactory(SimpleXmlConverterFactory.create(serializer))
.addCallAdapterFactory(SynchronousCallAdapterFactory.create())
.build();
return retrofit.create(EnvelopeSender.class);
}
Serialisation factory is as follow.
public class XMLSerializerFactory {
private Strategy strategy;
private DateFormat format;
private RegistryMatcher registryMatcher;
public Serializer getSerializer() {
if (strategy == null && registryMatcher == null) {
return new Persister();
} else if (strategy == null) {
return new Persister(registryMatcher);
} else if (registryMatcher == null) {
return new Persister(strategy);
} else {
return new Persister(strategy, registryMatcher);
}
}
public XMLSerializerFactory withStrategy() {
strategy = new AnnotationStrategy();
return this;
}
public XMLSerializerFactory withDateFormat() {
format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.UK);
return this;
}
public XMLSerializerFactory withRegistryMatcher() {
if (format == null)
format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.UK);
registryMatcher = new RegistryMatcher();
registryMatcher.bind(Date.class, new DateFormatTransformer(format));
return this;
}
}
public class DateFormatTransformer implements Transform<Date> {
private DateFormat dateFormat;
public DateFormatTransformer(DateFormat dateFormat) {
this.dateFormat = dateFormat;
}
#Override
public Date read(String value) throws Exception {
return dateFormat.parse(value);
}
#Override
public String write(Date value) throws Exception {
return dateFormat.format(value);
}
}
Is it bug or I am doing something wrong?
Thanks in advance.

Related

Specify an adapter for multiple xsd types

I'm trying to map different formats onto 3 xsd types, xs:dateTime, xs:date, and xs:time. I'm doing a bit of codegen in my project, and do not have a bindings file, though I do have a package-info.
#javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters({
#javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(value = com.codegen.pojo.lib.adapters.XmlDateTimeFormatter.class, type = com.codegen.pojo.lib.types.IXmlDateTime.class)
})
#javax.xml.bind.annotation.XmlSchemaTypes({
#javax.xml.bind.annotation.XmlSchemaType(name = "dateTime", type = com.codegen.pojo.lib.types.XmlDateTime.class),
#javax.xml.bind.annotation.XmlSchemaType(name = "date", type = com.codegen.pojo.lib.types.XmlDate.class),
#javax.xml.bind.annotation.XmlSchemaType(name = "time", type = com.codegen.pojo.lib.types.XmlTime.class)
})
#com.codegen.pojo.lib.annotations.XMLDateTimeFormat(format = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXX")
#com.codegen.pojo.lib.annotations.XMLDateFormat(format = "yyyy-MM-dd'T'")
#com.codegen.pojo.lib.annotations.XMLTimeFormat(format = "'T'HH:mm:ss.SSSXXXX")
package my_pkg;
All 3 of the Xml(Date/Time) classes mentioned in the XmlSchemaType annotations implement the IXmlDateTime interface.
The adapter:
public class XmlDateTimeFormatter extends XmlAdapter<String, IXmlDateTime> {
private final DateTimeFormatter dateTimeFormat;
private final DateTimeFormatter dateFormat;
private final DateTimeFormatter timeFormat;
public XmlDateTimeFormatter(String dateTimeFormatPattern, String dateFormatPattern, String timeFormatPattern) {
dateTimeFormat = dateTimeFormatPattern == null ? null : DateTimeFormatter.ofPattern(dateTimeFormatPattern);
dateFormat = dateFormatPattern == null ? null : DateTimeFormatter.ofPattern(dateFormatPattern);
timeFormat = timeFormatPattern == null ? null : DateTimeFormatter.ofPattern(timeFormatPattern);
}
#Override
public String marshal(IXmlDateTime dateTime) throws Exception {
if (dateTime instanceof XmlDateTime) {
return dateTimeFormat.format(dateTime.getCalendar().toGregorianCalendar().toZonedDateTime());
} else if (dateTime instanceof XmlDate) {
return dateFormat.format(dateTime.getCalendar().toGregorianCalendar().toZonedDateTime());
} else if (dateTime instanceof XmlTime) {
return timeFormat.format(dateTime.getCalendar().toGregorianCalendar().toZonedDateTime());
}
return null;
}
#Override
public IXmlDateTime unmarshal(String dateTime) throws Exception {
XMLGregorianCalendar calendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(dateTime);
QName xmlFormat = calendar.getXMLSchemaType();
if (xmlFormat.equals(DatatypeConstants.DATETIME)) {
return new XmlDateTime(calendar);
} else if (xmlFormat.equals(DatatypeConstants.DATE)) {
return new XmlDate(calendar);
} else if (xmlFormat.equals(DatatypeConstants.TIME)) {
return new XmlTime(calendar);
}
return null;
}
The adapter is added to a Marshaller/Unmarshaller created from a JAXBContext. Unfortunately, neither the marshal or unmarshal get called. Any thoughts on how I could fix this?

How to fix API authentication problem in Kotlin Android app?

I developed an API in Laravel for reading some data with authentication. Now in my app I need to send the token in my header for API to respond. Every time i login with app, I'm getting token without problem, but i can't provide token in header and it's returning a null token response. Now every time i reopen my app everything is fine but problem appear only when i login.
Please read my code and say if you found the bug.
This is my (AppServer.kt). I use this for adding the token to my header
class AppServer private constructor(private val client: INetworkClient) : IAppServer {
private val gson = Gson()
companion object {
private var instance: AppServer? = null
fun getInstance(): AppServer {
val token = AppLoggedInUser.getInstance()?.userProfile?.userToken ?: ""
if (instance == null)
instance = AppServer(
MixedNetworkClient(
mHeaders = mutableMapOf(
Headers.CONTENT_TYPE to "application/json",
"X-Requested-With" to "XMLHttpRequest",
"Authorization" to "Bearer $token"
),
mBasePath = "https://myWebsiteURL.com/"
)
)
return instance!!
}
}
override fun getPurchasedItems(): Observable<Pair<ResponseState, List<OrderInfo>?>> {
return Observable.create<Pair<ResponseState, List<OrderInfo>?>> { emitter ->
val (items, statusCode, msg, error) =
client.get(
"api/users/${AppLoggedInUser.getInstance().userProfile.userId}/orders",
{ responseStr ->
try {
val orders = mutableListOf<OrderInfo>()
val jArray = JSONArray(responseStr)
for (i in 0 until jArray.length()) {
val jObject = jArray.getJSONObject(i)
val order =
gson.fromJson<OrderInfo>(jObject.toString(), OrderInfo::class.java)
if (order.isPaymentSuccessful)
orders.add(order)
}
if (orders.isEmpty())
emitter.onNext(pair(empty(), null))
else
emitter.onNext(pair(success(), orders))
} catch (t: Throwable) {
Timber.e(t)
emitter.onNext(pair(ResponseState.internalError(t), null))
}
})
}.attachSchedulers()
}
override fun getDiscountDetailsById(id: Int): Observable<Pair<ResponseState, DiscountDetails?>> {
return Observable.create<Pair<ResponseState, DiscountDetails?>> { emitter ->
try {
client.post("api/post", listOf("post_id" to id.toString())) { responseStr ->
val jObject = JSONObject(responseStr)
var discount: DiscountDetails? = null
if (jObject.has("ID"))
discount =
gson.fromJson<DiscountDetails>(jObject.toString(), DiscountDetails::class.java)
if (discount != null)
emitter.onNext(pair(success(), discount))
else
emitter.onNext(pair(notFound404(), null))
}
} catch (t: Throwable) {
Timber.e(t)
emitter.onNext(pair(ResponseState.internalError(t), null))
}
}.attachSchedulers()
}
}
and this is my (AppLoggedInUser.java) I use it for getting my current user token.
package com.fartaak.gilantakhfif.utilities;
import android.content.Context;
import com.fartaak.gilantakhfif.backend.server.ParsingGSON;
import com.fartaak.gilantakhfif.model.UserProfile;
public class AppLoggedInUser extends AppPreferences {
public static final String NAM_LOGIN_SdPs = "login";
public static final String KEY_USER_TOKEN = "tokenPor";
private static AppLoggedInUser mInstance;
private final String KEY_LOGIN = "prefP";
private boolean isCompletelyRegistered;
public static void init(Context context) {
if (mInstance == null) {
mInstance = new AppLoggedInUser(context);
}
}
public static AppLoggedInUser getInstance() {
if (mInstance != null) {
return mInstance;
} else {
throw new IllegalStateException(
"you should call init to initialize only once per app launch before calling getInstance");
}
}
private AppLoggedInUser(Context context) {
super(NAM_LOGIN_SdPs, context);
}
public String getUserToken() {
return getField(KEY_USER_TOKEN);
}
public void clearUserProfile() {
removeField(KEY_LOGIN);
}
public UserProfile getUserProfile() {
String data = getField(KEY_LOGIN);
if (data == null) {
return null;
}
//return new Gson().fromJson(data, UserProfile.class);
return ParsingGSON.getInstance().getParsingJSONObject(data, UserProfile.class, null);
}
public boolean isRegisterCompleted() {
if (!isCompletelyRegistered) {
UserProfile userProfile = getUserProfile();
if (userProfile.getUserName() == null) {
return false;
} else {
isCompletelyRegistered = true;
}
}
return true;
}
public boolean isUserProfile() {
return isField(KEY_LOGIN);
}
public void setUserProfile(UserProfile userProfile) {
String json = ParsingGSON.getInstance().toJSONObject(userProfile, UserProfile.class, null);
setField(KEY_LOGIN, json);
}
}
I think the problem is with my second class.

Why updating broadcast variable sample code didn't work?

I want to update broadcast variable every minute. So I use the sample code you give by Aastha in this question.
how can I update a broadcast variable in Spark streaming?
But it didn't work. The function updateAndGet() only works when the streaming application start. When I debug my code , it didn't went into the fuction updateAndGet() twice. So the broadcast variable didn't update every minute.
Why?
Here is my sample code.
public class BroadcastWrapper {
private Broadcast<List<String>> broadcastVar;
private Date lastUpdatedAt = Calendar.getInstance().getTime();
private static BroadcastWrapper obj = new BroadcastWrapper();
private BroadcastWrapper(){}
public static BroadcastWrapper getInstance() {
return obj;
}
public JavaSparkContext getSparkContext(SparkContext sc) {
JavaSparkContext jsc = JavaSparkContext.fromSparkContext(sc);
return jsc;
}
public Broadcast<List<String>> updateAndGet(JavaStreamingContext jsc) {
Date currentDate = Calendar.getInstance().getTime();
long diff = currentDate.getTime()-lastUpdatedAt.getTime();
if (broadcastVar == null || diff > 60000) { // Lets say we want to refresh every 1 min =
// 60000 ms
if (broadcastVar != null)
broadcastVar.unpersist();
lastUpdatedAt = new Date(System.currentTimeMillis());
// Your logic to refreshs
// List<String> data = getRefData();
List<String> data = new ArrayList<String>();
data.add("tang");
data.add("xiao");
data.add(String.valueOf(System.currentTimeMillis()));
broadcastVar = jsc.sparkContext().broadcast(data);
}
return broadcastVar;}}
//Here is the computing code submit to spark streaming.
lines.transform(new Function<JavaRDD<String>, JavaRDD<String>>() {
Broadcast<List<String>> blacklist =
BroadcastWrapper.getInstance().updateAndGet(jsc);
#Override
public JavaRDD<String> call(JavaRDD<String> rdd) {
JavaRDD<String> dd=rdd.filter(new Function<String, Boolean>() {
#Override
public Boolean call(String word) {
if (blacklist.getValue().contains(word)) {
return false;
} else {
return true;
}
}
});
return dd;
}});

Why is this cache not getting evicted?

AdminSOAPRunner:
#Component
public class AdminSOAPRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(AdminSOAPRunner.class);
private String userId;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
#Autowired
private AdminAuth adminAuthenticator;
#Autowired
private AdminBean adminBean;
private AccountService accountService;
private void setBindingProviderByAccountService() {
WSBindingProvider bindingProvider = (WSBindingProvider) this.accountService;
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, adminBean.getAccountUrl());
LOGGER.info("Endpoint {}", adminBean.getAccountUrl());
}
private RequestInfo getRequestInfo() {
RequestInfo requestInfo = new RequestInfo();
requestInfo.setAppName(adminBean.getAppName());
requestInfo.setUserId(this.getUserId());
requestInfo.setTrace(UUID.randomUUID().toString());
return requestInfo;
}
public List<ApplyAccountResult> getAccounts(ApplyAccountRequest request) {
AccountService_Service service = null;
URL serviceWSDL = AccountService_Service.class.getResource("/Account-service/Account-service.wsdl");
service = new AccountService_Service(serviceWSDL);
SOAPHandlerResolver SOAPHandlerResolver = new SOAPHandlerResolver();
SOAPHandlerResolver.getHandlerList().add(new SOAPHandler(this.adminAuthenticator));
service.setHandlerResolver(SOAPHandlerResolver);
if (accountService == null) {
accountService = service.getAccountService();
}
setBindingProviderByAccountService();
ApplyAccountAccountResponse response = null;
LOGGER.info("Making a SOAP request.");
response = AccountService.applyAccount(request, getRequestInfo(), new Holder<ResponseInfo>());
LOGGER.info("SOAP request completed.");
return response.getApplyAccountResults();
}
SOAPHandlerResolver:
public class SOAPHandlerResolver implements HandlerResolver {
#SuppressWarnings("rawtypes")
private List<Handler> handlerList;
public SOAPHandlerResolver() {
this.handlerList = null;
}
#SuppressWarnings("rawtypes")
public List<Handler> getHandlerList() {
if (this.handlerList == null) {
this.handlerList = new ArrayList<>();
}
return this.handlerList;
}
#SuppressWarnings("rawtypes")
#Override
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<>();
if (this.handlerList == null || this.handlerList.isEmpty()) {
this.handlerList = new ArrayList<>();
this.handlerList.add(new SOAPHandler(null));
}
handlerChain.addAll(this.handlerList);
return handlerChain;
}
}
SOAPHandler
public class SOAPHandler implements SOAPHandler<SOAPMessageContext> {
private AdminAuth adminAuth;
private static final Logger LOGGER = LoggerFactory.getLogger(SOAPHandler.class);
public MosaicOnboardSOAPHandler(AdminAuth adminAuth) {
if (adminAuth == null) {
adminAuth = new AdminAuth();
LOGGER.info("AdminAuth found null. Creating new adminAuth instance.");
}
this.adminAuth = adminAuth;
}
#Override
public boolean handleMessage(SOAPMessageContext context) {
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty) {
#SuppressWarnings("unchecked")
Map<String, List<String>> headers = (Map<String, List<String>>) context.get(MessageContext.HTTP_REQUEST_HEADERS);
if (headers == null) {
headers = new HashMap<>();
context.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
}
List<String> cookie = headers.get("Cookie");
if (cookie == null) {
cookie = new ArrayList<>();
headers.put("Cookie", cookie);
}
cookie.add(this.adminAuth.getToken());
}
return true;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
return false;
}
#Override
public void close(MessageContext context) {
}
#Override
public Set<QName> getHeaders() {
return null;
}
}
AdminAuth:
#Component
public class AdminAuth {
#Autowired
private AdminBean adminBean;
private static final Logger LOG = LoggerFactory.getLogger(Admin.class);
private String token;
private void generateToken() {
try {
AdminTokenHelper adminTokenHelper = new AdminTokenHelper(adminBean.getAutheticationServerURL(), adminBean.getLicense());
token = adminTokenHelper.getToken(adminBean.getUsername(), adminBean.getPassword().toCharArray());
LOG.info("Token generation successful");
} catch (Exception ex) {
ex.printStackTrace();
LOG.error("Token generation failed");
LOG.error(ex.getMessage());
throw new RuntimeException("Token generation failed", ex);
}
}
#Cacheable(value = "tokenCache")
public String getToken() {
LOG.warn("Token not available. Generating a new token.");
generateToken();
return token;
}
}
ehcache.xml
<cache name="tokenCache" maxEntriesLocalHeap="1" eternal="false" timeToIdleSeconds="895" timeToLiveSeconds="895" memoryStoreEvictionPolicy="LRU"/>
Applcation
#EnableCaching
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(Application.class).profiles(determineEnvironmentProfile());
}
}
In AdminAuth, it uses functional user to generate token. the token generated for authentication expires in 15 minutes. So my purpose was to write cache so that all the calls from ui can use the same token regardless of actual user. So i set the time 14:55 to generate new token. Now the problem comes when it's after 15 minutes and the cache doesn't evict the old toeken so that call uses the old and expired token and it fails.
I tried different eviction policies like LRU, LFU, FiFO but nothing is working. The calls are coming from ui through tomcat container in spring boot 1.3.
Why is this not getting evicted? What am i missing? Any help is appreciated
Replace #Cacheable(value = "tokenCache") with #Cacheable("tokenCache")
From the comments:
The dependency on spring-boot-starter-cache was missing. This prevented Spring Boot from automatically configuring the CacheManager. Once this dependency was added, the cache configuration worked.
See http://docs.spring.io/spring-boot/docs/1.3.x/reference/html/boot-features-caching.html

JavaFX TreeView JSON Ex/Import via GSON

I´m looking for a way to export a JavaFX TreeView to JSON. To make this whole process simple, I use GSON. Its exporting the value of a treeItem well, but when I try to use the whole Tree its ending in a stack overflow. I believe this has something to do with the parent/child attribute. Is there a way to prevent GSON from exporting this attribute.
And how do I import the whole thing again? I wasn't able to import a simple object of mine, because GSON can't handle Properties.
You need to use a custom type adapter. Furthermore you can prevent stackoverflows by using loops instead of recursion:
public class TreeItemTypeAdapter<T> extends TypeAdapter<TreeItem<T>> {
private Gson gson;
public void setGson(Gson gson) {
this.gson = gson;
}
private final Class<T> valueClass;
public TreeItemTypeAdapter(Class<T> valueClass) {
if (valueClass == null) {
throw new IllegalArgumentException();
}
this.valueClass = valueClass;
}
public static TreeItemTypeAdapter<String> createStringTreeItemAdapter() {
return new TreeItemTypeAdapter<>(String.class);
}
private void writeValue(JsonWriter writer, T t) throws IOException {
if (gson == null) {
writer.value(Objects.toString(t, null));
} else {
gson.toJson(t, valueClass, writer);
}
}
private T readValue(JsonReader reader) throws IOException {
if (gson == null) {
Object value = reader.nextString();
return (T) value;
} else {
return gson.fromJson(reader, valueClass);
}
}
#Override
public void write(JsonWriter writer, TreeItem<T> t) throws IOException {
writer.beginObject().name("value");
writeValue(writer, t.getValue());
writer.name("children").beginArray();
LinkedList<Iterator<TreeItem<T>>> iterators = new LinkedList<>();
iterators.add(t.getChildren().iterator());
while (!iterators.isEmpty()) {
Iterator<TreeItem<T>> last = iterators.peekLast();
if (last.hasNext()) {
TreeItem<T> ti = last.next();
writer.beginObject().name("value");
writeValue(writer, ti.getValue());
writer.name("children").beginArray();
iterators.add(ti.getChildren().iterator());
} else {
writer.endArray().endObject();
iterators.pollLast();
}
}
}
#Override
public TreeItem<T> read(JsonReader reader) throws IOException {
if (gson == null && !valueClass.getName().equals("java.lang.String")) {
throw new IllegalStateException("cannot parse classes other than String without gson provided");
}
reader.beginObject();
if (!"value".equals(reader.nextName())) {
throw new IOException("value expected");
}
TreeItem<T> root = new TreeItem<>(readValue(reader));
TreeItem<T> item = root;
if (!"children".equals(reader.nextName())) {
throw new IOException("children expected");
}
reader.beginArray();
int depth = 1;
while (depth > 0) {
if (reader.hasNext()) {
reader.beginObject();
if (!"value".equals(reader.nextName())) {
throw new IOException("value expected");
}
TreeItem<T> newItem = new TreeItem<>(readValue(reader));
item.getChildren().add(newItem);
item = newItem;
if (!"children".equals(reader.nextName())) {
throw new IOException("children expected");
}
reader.beginArray();
depth++;
} else {
depth--;
reader.endArray();
reader.endObject();
item = item.getParent();
}
}
return root;
}
}
public static void main(String[] args) {
TreeItem<String> ti = new TreeItem<>("Hello world");
TreeItem<String> ti2 = new TreeItem<>("42");
TreeItem<String> ti3 = new TreeItem<>("Foo");
TreeItem<String> ti4 = new TreeItem<>("Bar");
ti.getChildren().addAll(ti2, ti3);
ti2.getChildren().add(ti4);
TreeItemTypeAdapter<String> adapter = new TreeItemTypeAdapter<>(String.class);
Gson gson = new GsonBuilder().registerTypeAdapter(TreeItem.class, adapter).create();
adapter.setGson(gson);
System.out.println(gson.toJson(ti));
System.out.println(toString(gson.fromJson("{\"value\":\"Hello world\",\"children\":[{\"value\":\"42\",\"children\":[{\"value\":\"Bar\",\"children\":[]}]},{\"value\":\"Foo\",\"children\":[]}]}",
TreeItem.class)));
}
private static String toString(TreeItem ti) {
StringBuilder sb = new StringBuilder("TreeItem [ value: \"").append(ti.getValue()).append("\" children [");
boolean notFirst = false;
for (TreeItem i : (List<TreeItem>) ti.getChildren()) {
if (notFirst) {
sb.append(",");
} else {
notFirst = true;
}
sb.append(toString(i));
}
return sb.append("]]").toString();
}

Categories